xref: /onnv-gate/usr/src/cmd/dd/dd.c (revision 0)
1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate  * CDDL HEADER START
3*0Sstevel@tonic-gate  *
4*0Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*0Sstevel@tonic-gate  * with the License.
8*0Sstevel@tonic-gate  *
9*0Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate  * and limitations under the License.
13*0Sstevel@tonic-gate  *
14*0Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate  *
20*0Sstevel@tonic-gate  * CDDL HEADER END
21*0Sstevel@tonic-gate  */
22*0Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*0Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*0Sstevel@tonic-gate 
25*0Sstevel@tonic-gate 
26*0Sstevel@tonic-gate /*
27*0Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28*0Sstevel@tonic-gate  * Use is subject to license terms.
29*0Sstevel@tonic-gate  */
30*0Sstevel@tonic-gate 
31*0Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*0Sstevel@tonic-gate 
33*0Sstevel@tonic-gate /*
34*0Sstevel@tonic-gate  *	convert and copy
35*0Sstevel@tonic-gate  */
36*0Sstevel@tonic-gate 
37*0Sstevel@tonic-gate #include	<stdio.h>
38*0Sstevel@tonic-gate #include	<signal.h>
39*0Sstevel@tonic-gate #include	<fcntl.h>
40*0Sstevel@tonic-gate #include	<sys/param.h>
41*0Sstevel@tonic-gate #include	<sys/types.h>
42*0Sstevel@tonic-gate #include	<sys/sysmacros.h>
43*0Sstevel@tonic-gate #include	<sys/stat.h>
44*0Sstevel@tonic-gate #include	<unistd.h>
45*0Sstevel@tonic-gate #include	<stdlib.h>
46*0Sstevel@tonic-gate #include	<locale.h>
47*0Sstevel@tonic-gate #include	<string.h>
48*0Sstevel@tonic-gate 
49*0Sstevel@tonic-gate /* The BIG parameter is machine dependent.  It should be a long integer	*/
50*0Sstevel@tonic-gate /* constant that can be used by the number parser to check the validity	*/
51*0Sstevel@tonic-gate /* of numeric parameters.  On 16-bit machines, it should probably be	*/
52*0Sstevel@tonic-gate /* the maximum unsigned integer, 0177777L.  On 32-bit machines where	*/
53*0Sstevel@tonic-gate /* longs are the same size as ints, the maximum signed integer is more	*/
54*0Sstevel@tonic-gate /* appropriate.  This value is 017777777777L. In 64 bit environments,   */
55*0Sstevel@tonic-gate /* the maximum signed integer value is 0777777777777777777777LL		*/
56*0Sstevel@tonic-gate 
57*0Sstevel@tonic-gate #define	BIG	0777777777777777777777LL
58*0Sstevel@tonic-gate 
59*0Sstevel@tonic-gate #define	BSIZE	512
60*0Sstevel@tonic-gate 
61*0Sstevel@tonic-gate /* Option parameters */
62*0Sstevel@tonic-gate 
63*0Sstevel@tonic-gate #define	COPY		0	/* file copy, preserve input block size */
64*0Sstevel@tonic-gate #define	REBLOCK		1	/* file copy, change block size */
65*0Sstevel@tonic-gate #define	LCREBLOCK	2	/* file copy, convert to lower case */
66*0Sstevel@tonic-gate #define	UCREBLOCK	3	/* file copy, convert to upper case */
67*0Sstevel@tonic-gate #define	NBASCII		4	/* file copy, convert from EBCDIC to ASCII */
68*0Sstevel@tonic-gate #define	LCNBASCII	5	/* file copy, EBCDIC to lower case ASCII */
69*0Sstevel@tonic-gate #define	UCNBASCII	6	/* file copy, EBCDIC to upper case ASCII */
70*0Sstevel@tonic-gate #define	NBEBCDIC	7	/* file copy, convert from ASCII to EBCDIC */
71*0Sstevel@tonic-gate #define	LCNBEBCDIC	8	/* file copy, ASCII to lower case EBCDIC */
72*0Sstevel@tonic-gate #define	UCNBEBCDIC	9	/* file copy, ASCII to upper case EBCDIC */
73*0Sstevel@tonic-gate #define	NBIBM		10	/* file copy, convert from ASCII to IBM */
74*0Sstevel@tonic-gate #define	LCNBIBM		11	/* file copy, ASCII to lower case IBM */
75*0Sstevel@tonic-gate #define	UCNBIBM		12	/* file copy, ASCII to upper case IBM */
76*0Sstevel@tonic-gate #define	UNBLOCK		13	/* convert blocked ASCII to ASCII */
77*0Sstevel@tonic-gate #define	LCUNBLOCK	14	/* convert blocked ASCII to lower case ASCII */
78*0Sstevel@tonic-gate #define	UCUNBLOCK	15	/* convert blocked ASCII to upper case ASCII */
79*0Sstevel@tonic-gate #define	ASCII		16	/* convert blocked EBCDIC to ASCII */
80*0Sstevel@tonic-gate #define	LCASCII		17	/* convert blocked EBCDIC to lower case ASCII */
81*0Sstevel@tonic-gate #define	UCASCII		18	/* convert blocked EBCDIC to upper case ASCII */
82*0Sstevel@tonic-gate #define	BLOCK		19	/* convert ASCII to blocked ASCII */
83*0Sstevel@tonic-gate #define	LCBLOCK		20	/* convert ASCII to lower case blocked ASCII */
84*0Sstevel@tonic-gate #define	UCBLOCK		21	/* convert ASCII to upper case blocked ASCII */
85*0Sstevel@tonic-gate #define	EBCDIC		22	/* convert ASCII to blocked EBCDIC */
86*0Sstevel@tonic-gate #define	LCEBCDIC	23	/* convert ASCII to lower case blocked EBCDIC */
87*0Sstevel@tonic-gate #define	UCEBCDIC	24	/* convert ASCII to upper case blocked EBCDIC */
88*0Sstevel@tonic-gate #define	IBM		25	/* convert ASCII to blocked IBM */
89*0Sstevel@tonic-gate #define	LCIBM		26	/* convert ASCII to lower case blocked IBM */
90*0Sstevel@tonic-gate #define	UCIBM		27	/* convert ASCII to upper case blocked IBM */
91*0Sstevel@tonic-gate #define	LCASE		01	/* flag - convert to lower case */
92*0Sstevel@tonic-gate #define	UCASE		02	/* flag - convert to upper case */
93*0Sstevel@tonic-gate #define	SWAB		04	/* flag - swap bytes before conversion */
94*0Sstevel@tonic-gate #define	NERR		010	/* flag - proceed on input errors */
95*0Sstevel@tonic-gate #define	SYNC		020	/* flag - pad short input blocks with nulls */
96*0Sstevel@tonic-gate #define	BADLIMIT	5	/* give up if no progress after BADLIMIT trys */
97*0Sstevel@tonic-gate #define	SVR4XLATE	0	/* use default EBCDIC translation */
98*0Sstevel@tonic-gate #define	BSDXLATE	1	/* use BSD-compatible EBCDIC translation */
99*0Sstevel@tonic-gate 
100*0Sstevel@tonic-gate #define	USAGE\
101*0Sstevel@tonic-gate 	"usage: dd [if=file] [of=file] [ibs=n|nk|nb|nxm] [obs=n|nk|nb|nxm]\n"\
102*0Sstevel@tonic-gate 	"	   [bs=n|nk|nb|nxm] [cbs=n|nk|nb|nxm] [files=n] [skip=n]\n"\
103*0Sstevel@tonic-gate 	"	   [iseek=n] [oseek=n] [seek=n] [count=n] [conv=[ascii]\n"\
104*0Sstevel@tonic-gate 	"	   [,ebcdic][,ibm][,asciib][,ebcdicb][,ibmb]\n"\
105*0Sstevel@tonic-gate 	"	   [,block|unblock][,lcase|ucase][,swab]\n"\
106*0Sstevel@tonic-gate 	"	   [,noerror][,notrunc][,sync]]\n"
107*0Sstevel@tonic-gate 
108*0Sstevel@tonic-gate /* Global references */
109*0Sstevel@tonic-gate 
110*0Sstevel@tonic-gate /* Local routine declarations */
111*0Sstevel@tonic-gate 
112*0Sstevel@tonic-gate static int	match(char *);
113*0Sstevel@tonic-gate static void		term();
114*0Sstevel@tonic-gate static unsigned long long	number();
115*0Sstevel@tonic-gate static unsigned char	*flsh();
116*0Sstevel@tonic-gate static void		stats();
117*0Sstevel@tonic-gate 
118*0Sstevel@tonic-gate /* Local data definitions */
119*0Sstevel@tonic-gate 
120*0Sstevel@tonic-gate static unsigned ibs;	/* input buffer size */
121*0Sstevel@tonic-gate static unsigned obs;	/* output buffer size */
122*0Sstevel@tonic-gate static unsigned bs;	/* buffer size, overrules ibs and obs */
123*0Sstevel@tonic-gate static unsigned cbs;	/* conversion buffer size, used for block conversions */
124*0Sstevel@tonic-gate static unsigned ibc;	/* number of bytes still in the input buffer */
125*0Sstevel@tonic-gate static unsigned obc;	/* number of bytes in the output buffer */
126*0Sstevel@tonic-gate static unsigned cbc;	/* number of bytes in the conversion buffer */
127*0Sstevel@tonic-gate 
128*0Sstevel@tonic-gate static int	ibf;	/* input file descriptor */
129*0Sstevel@tonic-gate static int	obf;	/* output file descriptor */
130*0Sstevel@tonic-gate static int	cflag;	/* conversion option flags */
131*0Sstevel@tonic-gate static int	skipf;	/* if skipf == 1, skip rest of input line */
132*0Sstevel@tonic-gate static unsigned long long	nifr;	/* count of full input records */
133*0Sstevel@tonic-gate static unsigned long long	nipr;	/* count of partial input records */
134*0Sstevel@tonic-gate static unsigned long long	nofr;	/* count of full output records */
135*0Sstevel@tonic-gate static unsigned long long	nopr;	/* count of partial output records */
136*0Sstevel@tonic-gate static unsigned long long	ntrunc;	/* count of truncated input lines */
137*0Sstevel@tonic-gate static unsigned long long	nbad;	/* count of bad records since last */
138*0Sstevel@tonic-gate 					/* good one */
139*0Sstevel@tonic-gate static int	files;	/* number of input files to concatenate (tape only) */
140*0Sstevel@tonic-gate static off_t	skip;	/* number of input records to skip */
141*0Sstevel@tonic-gate static off_t	iseekn;	/* number of input records to seek past */
142*0Sstevel@tonic-gate static off_t	oseekn;	/* number of output records to seek past */
143*0Sstevel@tonic-gate static unsigned long long	count;	/* number of input records to copy */
144*0Sstevel@tonic-gate 			/* (0 = all) */
145*0Sstevel@tonic-gate static int	trantype; /* BSD or SVr4 compatible EBCDIC */
146*0Sstevel@tonic-gate 
147*0Sstevel@tonic-gate static char		*string;	/* command arg pointer */
148*0Sstevel@tonic-gate static char		*ifile;		/* input file name pointer */
149*0Sstevel@tonic-gate static char		*ofile;		/* output file name pointer */
150*0Sstevel@tonic-gate static unsigned char	*ibuf;		/* input buffer pointer */
151*0Sstevel@tonic-gate static unsigned char	*obuf;		/* output buffer pointer */
152*0Sstevel@tonic-gate 
153*0Sstevel@tonic-gate /* This is an EBCDIC to ASCII conversion table	*/
154*0Sstevel@tonic-gate /* from a proposed BTL standard April 16, 1979	*/
155*0Sstevel@tonic-gate 
156*0Sstevel@tonic-gate static unsigned char svr4_etoa [] =
157*0Sstevel@tonic-gate {
158*0Sstevel@tonic-gate 	0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
159*0Sstevel@tonic-gate 	0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
160*0Sstevel@tonic-gate 	0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
161*0Sstevel@tonic-gate 	0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
162*0Sstevel@tonic-gate 	0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
163*0Sstevel@tonic-gate 	0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
164*0Sstevel@tonic-gate 	0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
165*0Sstevel@tonic-gate 	0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
166*0Sstevel@tonic-gate 	0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
167*0Sstevel@tonic-gate 	0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
168*0Sstevel@tonic-gate 	0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
169*0Sstevel@tonic-gate 	0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
170*0Sstevel@tonic-gate 	0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
171*0Sstevel@tonic-gate 	0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
172*0Sstevel@tonic-gate 	0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
173*0Sstevel@tonic-gate 	0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
174*0Sstevel@tonic-gate 	0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
175*0Sstevel@tonic-gate 	0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
176*0Sstevel@tonic-gate 	0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
177*0Sstevel@tonic-gate 	0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
178*0Sstevel@tonic-gate 	0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
179*0Sstevel@tonic-gate 	0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
180*0Sstevel@tonic-gate 	0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
181*0Sstevel@tonic-gate 	0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
182*0Sstevel@tonic-gate 	0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
183*0Sstevel@tonic-gate 	0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
184*0Sstevel@tonic-gate 	0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
185*0Sstevel@tonic-gate 	0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
186*0Sstevel@tonic-gate 	0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
187*0Sstevel@tonic-gate 	0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
188*0Sstevel@tonic-gate 	0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
189*0Sstevel@tonic-gate 	0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
190*0Sstevel@tonic-gate };
191*0Sstevel@tonic-gate 
192*0Sstevel@tonic-gate /* This is an ASCII to EBCDIC conversion table	*/
193*0Sstevel@tonic-gate /* from a proposed BTL standard April 16, 1979	*/
194*0Sstevel@tonic-gate 
195*0Sstevel@tonic-gate static unsigned char svr4_atoe [] =
196*0Sstevel@tonic-gate {
197*0Sstevel@tonic-gate 	0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
198*0Sstevel@tonic-gate 	0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
199*0Sstevel@tonic-gate 	0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
200*0Sstevel@tonic-gate 	0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
201*0Sstevel@tonic-gate 	0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
202*0Sstevel@tonic-gate 	0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
203*0Sstevel@tonic-gate 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
204*0Sstevel@tonic-gate 	0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
205*0Sstevel@tonic-gate 	0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
206*0Sstevel@tonic-gate 	0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
207*0Sstevel@tonic-gate 	0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
208*0Sstevel@tonic-gate 	0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155,
209*0Sstevel@tonic-gate 	0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
210*0Sstevel@tonic-gate 	0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
211*0Sstevel@tonic-gate 	0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
212*0Sstevel@tonic-gate 	0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007,
213*0Sstevel@tonic-gate 	0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
214*0Sstevel@tonic-gate 	0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
215*0Sstevel@tonic-gate 	0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
216*0Sstevel@tonic-gate 	0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
217*0Sstevel@tonic-gate 	0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
218*0Sstevel@tonic-gate 	0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
219*0Sstevel@tonic-gate 	0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
220*0Sstevel@tonic-gate 	0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
221*0Sstevel@tonic-gate 	0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
222*0Sstevel@tonic-gate 	0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236,
223*0Sstevel@tonic-gate 	0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257,
224*0Sstevel@tonic-gate 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
225*0Sstevel@tonic-gate 	0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277,
226*0Sstevel@tonic-gate 	0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
227*0Sstevel@tonic-gate 	0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
228*0Sstevel@tonic-gate 	0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
229*0Sstevel@tonic-gate };
230*0Sstevel@tonic-gate 
231*0Sstevel@tonic-gate /* Table for ASCII to IBM (alternate EBCDIC) code conversion	*/
232*0Sstevel@tonic-gate 
233*0Sstevel@tonic-gate static unsigned char svr4_atoibm[] =
234*0Sstevel@tonic-gate {
235*0Sstevel@tonic-gate 	0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
236*0Sstevel@tonic-gate 	0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
237*0Sstevel@tonic-gate 	0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
238*0Sstevel@tonic-gate 	0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
239*0Sstevel@tonic-gate 	0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
240*0Sstevel@tonic-gate 	0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
241*0Sstevel@tonic-gate 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
242*0Sstevel@tonic-gate 	0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
243*0Sstevel@tonic-gate 	0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
244*0Sstevel@tonic-gate 	0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
245*0Sstevel@tonic-gate 	0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
246*0Sstevel@tonic-gate 	0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
247*0Sstevel@tonic-gate 	0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
248*0Sstevel@tonic-gate 	0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
249*0Sstevel@tonic-gate 	0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
250*0Sstevel@tonic-gate 	0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
251*0Sstevel@tonic-gate 	0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
252*0Sstevel@tonic-gate 	0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
253*0Sstevel@tonic-gate 	0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
254*0Sstevel@tonic-gate 	0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
255*0Sstevel@tonic-gate 	0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
256*0Sstevel@tonic-gate 	0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
257*0Sstevel@tonic-gate 	0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
258*0Sstevel@tonic-gate 	0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
259*0Sstevel@tonic-gate 	0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
260*0Sstevel@tonic-gate 	0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
261*0Sstevel@tonic-gate 	0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
262*0Sstevel@tonic-gate 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
263*0Sstevel@tonic-gate 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
264*0Sstevel@tonic-gate 	0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
265*0Sstevel@tonic-gate 	0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
266*0Sstevel@tonic-gate 	0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
267*0Sstevel@tonic-gate };
268*0Sstevel@tonic-gate 
269*0Sstevel@tonic-gate /* Table for conversion of ASCII to lower case ASCII	*/
270*0Sstevel@tonic-gate 
271*0Sstevel@tonic-gate static unsigned char utol[] =
272*0Sstevel@tonic-gate {
273*0Sstevel@tonic-gate 	0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
274*0Sstevel@tonic-gate 	0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
275*0Sstevel@tonic-gate 	0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
276*0Sstevel@tonic-gate 	0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
277*0Sstevel@tonic-gate 	0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
278*0Sstevel@tonic-gate 	0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
279*0Sstevel@tonic-gate 	0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
280*0Sstevel@tonic-gate 	0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
281*0Sstevel@tonic-gate 	0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
282*0Sstevel@tonic-gate 	0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
283*0Sstevel@tonic-gate 	0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
284*0Sstevel@tonic-gate 	0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
285*0Sstevel@tonic-gate 	0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
286*0Sstevel@tonic-gate 	0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
287*0Sstevel@tonic-gate 	0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
288*0Sstevel@tonic-gate 	0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
289*0Sstevel@tonic-gate 	0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
290*0Sstevel@tonic-gate 	0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
291*0Sstevel@tonic-gate 	0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
292*0Sstevel@tonic-gate 	0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
293*0Sstevel@tonic-gate 	0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
294*0Sstevel@tonic-gate 	0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
295*0Sstevel@tonic-gate 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
296*0Sstevel@tonic-gate 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
297*0Sstevel@tonic-gate 	0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
298*0Sstevel@tonic-gate 	0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
299*0Sstevel@tonic-gate 	0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
300*0Sstevel@tonic-gate 	0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
301*0Sstevel@tonic-gate 	0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
302*0Sstevel@tonic-gate 	0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
303*0Sstevel@tonic-gate 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
304*0Sstevel@tonic-gate 	0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
305*0Sstevel@tonic-gate };
306*0Sstevel@tonic-gate 
307*0Sstevel@tonic-gate /* Table for conversion of ASCII to upper case ASCII	*/
308*0Sstevel@tonic-gate 
309*0Sstevel@tonic-gate static unsigned char ltou[] =
310*0Sstevel@tonic-gate {
311*0Sstevel@tonic-gate 	0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
312*0Sstevel@tonic-gate 	0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
313*0Sstevel@tonic-gate 	0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
314*0Sstevel@tonic-gate 	0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
315*0Sstevel@tonic-gate 	0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
316*0Sstevel@tonic-gate 	0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
317*0Sstevel@tonic-gate 	0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
318*0Sstevel@tonic-gate 	0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
319*0Sstevel@tonic-gate 	0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
320*0Sstevel@tonic-gate 	0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
321*0Sstevel@tonic-gate 	0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
322*0Sstevel@tonic-gate 	0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
323*0Sstevel@tonic-gate 	0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
324*0Sstevel@tonic-gate 	0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
325*0Sstevel@tonic-gate 	0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
326*0Sstevel@tonic-gate 	0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
327*0Sstevel@tonic-gate 	0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
328*0Sstevel@tonic-gate 	0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
329*0Sstevel@tonic-gate 	0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
330*0Sstevel@tonic-gate 	0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
331*0Sstevel@tonic-gate 	0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
332*0Sstevel@tonic-gate 	0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
333*0Sstevel@tonic-gate 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
334*0Sstevel@tonic-gate 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
335*0Sstevel@tonic-gate 	0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
336*0Sstevel@tonic-gate 	0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
337*0Sstevel@tonic-gate 	0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
338*0Sstevel@tonic-gate 	0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
339*0Sstevel@tonic-gate 	0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
340*0Sstevel@tonic-gate 	0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
341*0Sstevel@tonic-gate 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
342*0Sstevel@tonic-gate 	0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
343*0Sstevel@tonic-gate };
344*0Sstevel@tonic-gate 
345*0Sstevel@tonic-gate /* BSD-compatible EBCDIC to ASCII translate table */
346*0Sstevel@tonic-gate 
347*0Sstevel@tonic-gate static unsigned char	bsd_etoa[] =
348*0Sstevel@tonic-gate {
349*0Sstevel@tonic-gate 	0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
350*0Sstevel@tonic-gate 	0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
351*0Sstevel@tonic-gate 	0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
352*0Sstevel@tonic-gate 	0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
353*0Sstevel@tonic-gate 	0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
354*0Sstevel@tonic-gate 	0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
355*0Sstevel@tonic-gate 	0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
356*0Sstevel@tonic-gate 	0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
357*0Sstevel@tonic-gate 	0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
358*0Sstevel@tonic-gate 	0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041,
359*0Sstevel@tonic-gate 	0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
360*0Sstevel@tonic-gate 	0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136,
361*0Sstevel@tonic-gate 	0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
362*0Sstevel@tonic-gate 	0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077,
363*0Sstevel@tonic-gate 	0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
364*0Sstevel@tonic-gate 	0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
365*0Sstevel@tonic-gate 	0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
366*0Sstevel@tonic-gate 	0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
367*0Sstevel@tonic-gate 	0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
368*0Sstevel@tonic-gate 	0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
369*0Sstevel@tonic-gate 	0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
370*0Sstevel@tonic-gate 	0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
371*0Sstevel@tonic-gate 	0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
372*0Sstevel@tonic-gate 	0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
373*0Sstevel@tonic-gate 	0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
374*0Sstevel@tonic-gate 	0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
375*0Sstevel@tonic-gate 	0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
376*0Sstevel@tonic-gate 	0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
377*0Sstevel@tonic-gate 	0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
378*0Sstevel@tonic-gate 	0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
379*0Sstevel@tonic-gate 	0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
380*0Sstevel@tonic-gate 	0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
381*0Sstevel@tonic-gate };
382*0Sstevel@tonic-gate 
383*0Sstevel@tonic-gate /* BSD-compatible ASCII to EBCDIC translate table */
384*0Sstevel@tonic-gate 
385*0Sstevel@tonic-gate static unsigned char	bsd_atoe[] =
386*0Sstevel@tonic-gate {
387*0Sstevel@tonic-gate 	0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
388*0Sstevel@tonic-gate 	0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
389*0Sstevel@tonic-gate 	0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
390*0Sstevel@tonic-gate 	0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
391*0Sstevel@tonic-gate 	0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
392*0Sstevel@tonic-gate 	0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
393*0Sstevel@tonic-gate 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
394*0Sstevel@tonic-gate 	0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
395*0Sstevel@tonic-gate 	0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
396*0Sstevel@tonic-gate 	0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
397*0Sstevel@tonic-gate 	0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
398*0Sstevel@tonic-gate 	0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
399*0Sstevel@tonic-gate 	0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
400*0Sstevel@tonic-gate 	0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
401*0Sstevel@tonic-gate 	0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
402*0Sstevel@tonic-gate 	0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007,
403*0Sstevel@tonic-gate 	0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
404*0Sstevel@tonic-gate 	0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
405*0Sstevel@tonic-gate 	0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
406*0Sstevel@tonic-gate 	0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
407*0Sstevel@tonic-gate 	0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
408*0Sstevel@tonic-gate 	0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
409*0Sstevel@tonic-gate 	0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
410*0Sstevel@tonic-gate 	0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
411*0Sstevel@tonic-gate 	0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
412*0Sstevel@tonic-gate 	0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
413*0Sstevel@tonic-gate 	0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
414*0Sstevel@tonic-gate 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
415*0Sstevel@tonic-gate 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
416*0Sstevel@tonic-gate 	0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
417*0Sstevel@tonic-gate 	0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
418*0Sstevel@tonic-gate 	0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
419*0Sstevel@tonic-gate };
420*0Sstevel@tonic-gate 
421*0Sstevel@tonic-gate /* BSD-compatible ASCII to IBM translate table */
422*0Sstevel@tonic-gate 
423*0Sstevel@tonic-gate static unsigned char	bsd_atoibm[] =
424*0Sstevel@tonic-gate {
425*0Sstevel@tonic-gate 	0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
426*0Sstevel@tonic-gate 	0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
427*0Sstevel@tonic-gate 	0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
428*0Sstevel@tonic-gate 	0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
429*0Sstevel@tonic-gate 	0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
430*0Sstevel@tonic-gate 	0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
431*0Sstevel@tonic-gate 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
432*0Sstevel@tonic-gate 	0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
433*0Sstevel@tonic-gate 	0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
434*0Sstevel@tonic-gate 	0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
435*0Sstevel@tonic-gate 	0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
436*0Sstevel@tonic-gate 	0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
437*0Sstevel@tonic-gate 	0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
438*0Sstevel@tonic-gate 	0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
439*0Sstevel@tonic-gate 	0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
440*0Sstevel@tonic-gate 	0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
441*0Sstevel@tonic-gate 	0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
442*0Sstevel@tonic-gate 	0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
443*0Sstevel@tonic-gate 	0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
444*0Sstevel@tonic-gate 	0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
445*0Sstevel@tonic-gate 	0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
446*0Sstevel@tonic-gate 	0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
447*0Sstevel@tonic-gate 	0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
448*0Sstevel@tonic-gate 	0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
449*0Sstevel@tonic-gate 	0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
450*0Sstevel@tonic-gate 	0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
451*0Sstevel@tonic-gate 	0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
452*0Sstevel@tonic-gate 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
453*0Sstevel@tonic-gate 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
454*0Sstevel@tonic-gate 	0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
455*0Sstevel@tonic-gate 	0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
456*0Sstevel@tonic-gate 	0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
457*0Sstevel@tonic-gate };
458*0Sstevel@tonic-gate 
459*0Sstevel@tonic-gate /* set up to use SVr4 ascii-ebcdic translation by default */
460*0Sstevel@tonic-gate 
461*0Sstevel@tonic-gate static unsigned char *atoe = svr4_atoe;
462*0Sstevel@tonic-gate static unsigned char *etoa = svr4_etoa;
463*0Sstevel@tonic-gate static unsigned char *atoibm = svr4_atoibm;
464*0Sstevel@tonic-gate 
465*0Sstevel@tonic-gate 
466*0Sstevel@tonic-gate void
467*0Sstevel@tonic-gate main(argc, argv)
468*0Sstevel@tonic-gate int argc;
469*0Sstevel@tonic-gate char **argv;
470*0Sstevel@tonic-gate {
471*0Sstevel@tonic-gate 	unsigned char *ip, *op; /* input and output buffer pointers */
472*0Sstevel@tonic-gate 	int c;		/* character counter */
473*0Sstevel@tonic-gate 	int ic;		/* input character */
474*0Sstevel@tonic-gate 	int conv;		/* conversion option code */
475*0Sstevel@tonic-gate 	int trunc;		/* whether output file is truncated */
476*0Sstevel@tonic-gate 	struct stat file_stat;
477*0Sstevel@tonic-gate 
478*0Sstevel@tonic-gate 	/* Set option defaults */
479*0Sstevel@tonic-gate 
480*0Sstevel@tonic-gate 	ibs = BSIZE;
481*0Sstevel@tonic-gate 	obs = BSIZE;
482*0Sstevel@tonic-gate 	files = 1;
483*0Sstevel@tonic-gate 	conv = COPY;
484*0Sstevel@tonic-gate 	trunc = 1;			/* default: truncate output file */
485*0Sstevel@tonic-gate 	trantype = SVR4XLATE;  /* use SVR4 EBCDIC by default */
486*0Sstevel@tonic-gate 
487*0Sstevel@tonic-gate 	/* Parse command options */
488*0Sstevel@tonic-gate 
489*0Sstevel@tonic-gate 	(void) setlocale(LC_ALL, "");
490*0Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
491*0Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
492*0Sstevel@tonic-gate #endif
493*0Sstevel@tonic-gate 	(void) textdomain(TEXT_DOMAIN);
494*0Sstevel@tonic-gate 
495*0Sstevel@tonic-gate 	while ((c = getopt(argc, argv, "")) != EOF)
496*0Sstevel@tonic-gate 		switch (c) {
497*0Sstevel@tonic-gate 			case '?':
498*0Sstevel@tonic-gate 			(void) fprintf(stderr, USAGE);
499*0Sstevel@tonic-gate 			exit(2);
500*0Sstevel@tonic-gate 		}
501*0Sstevel@tonic-gate 
502*0Sstevel@tonic-gate 	/* not getopt()'ed because dd has no options but only operand(s) */
503*0Sstevel@tonic-gate 
504*0Sstevel@tonic-gate 	for (c = optind; c < argc; c++)
505*0Sstevel@tonic-gate 	{
506*0Sstevel@tonic-gate 		string = argv[c];
507*0Sstevel@tonic-gate 		if (match("ibs="))
508*0Sstevel@tonic-gate 		{
509*0Sstevel@tonic-gate 			ibs = (unsigned)number(BIG);
510*0Sstevel@tonic-gate 			continue;
511*0Sstevel@tonic-gate 		}
512*0Sstevel@tonic-gate 		if (match("obs="))
513*0Sstevel@tonic-gate 		{
514*0Sstevel@tonic-gate 			obs = (unsigned)number(BIG);
515*0Sstevel@tonic-gate 			continue;
516*0Sstevel@tonic-gate 		}
517*0Sstevel@tonic-gate 		if (match("cbs="))
518*0Sstevel@tonic-gate 		{
519*0Sstevel@tonic-gate 			cbs = (unsigned)number(BIG);
520*0Sstevel@tonic-gate 			continue;
521*0Sstevel@tonic-gate 		}
522*0Sstevel@tonic-gate 		if (match("bs="))
523*0Sstevel@tonic-gate 		{
524*0Sstevel@tonic-gate 			bs = (unsigned)number(BIG);
525*0Sstevel@tonic-gate 			continue;
526*0Sstevel@tonic-gate 		}
527*0Sstevel@tonic-gate 		if (match("if="))
528*0Sstevel@tonic-gate 		{
529*0Sstevel@tonic-gate 			ifile = string;
530*0Sstevel@tonic-gate 			continue;
531*0Sstevel@tonic-gate 		}
532*0Sstevel@tonic-gate 		if (match("of="))
533*0Sstevel@tonic-gate 		{
534*0Sstevel@tonic-gate 			ofile = string;
535*0Sstevel@tonic-gate 			continue;
536*0Sstevel@tonic-gate 		}
537*0Sstevel@tonic-gate 		if (match("skip="))
538*0Sstevel@tonic-gate 		{
539*0Sstevel@tonic-gate 			skip = number(BIG);
540*0Sstevel@tonic-gate 			continue;
541*0Sstevel@tonic-gate 		}
542*0Sstevel@tonic-gate 		if (match("iseek="))
543*0Sstevel@tonic-gate 		{
544*0Sstevel@tonic-gate 			iseekn = number(BIG);
545*0Sstevel@tonic-gate 			continue;
546*0Sstevel@tonic-gate 		}
547*0Sstevel@tonic-gate 		if (match("oseek="))
548*0Sstevel@tonic-gate 		{
549*0Sstevel@tonic-gate 			oseekn = number(BIG);
550*0Sstevel@tonic-gate 			continue;
551*0Sstevel@tonic-gate 		}
552*0Sstevel@tonic-gate 		if (match("seek="))		/* retained for compatibility */
553*0Sstevel@tonic-gate 		{
554*0Sstevel@tonic-gate 			oseekn = number(BIG);
555*0Sstevel@tonic-gate 			continue;
556*0Sstevel@tonic-gate 		}
557*0Sstevel@tonic-gate 		if (match("count="))
558*0Sstevel@tonic-gate 		{
559*0Sstevel@tonic-gate 			count = number(BIG);
560*0Sstevel@tonic-gate 			continue;
561*0Sstevel@tonic-gate 		}
562*0Sstevel@tonic-gate 		if (match("files="))
563*0Sstevel@tonic-gate 		{
564*0Sstevel@tonic-gate 			files = (int)number(BIG);
565*0Sstevel@tonic-gate 			continue;
566*0Sstevel@tonic-gate 		}
567*0Sstevel@tonic-gate 		if (match("conv="))
568*0Sstevel@tonic-gate 		{
569*0Sstevel@tonic-gate 			for (;;)
570*0Sstevel@tonic-gate 			{
571*0Sstevel@tonic-gate 				if (match(","))
572*0Sstevel@tonic-gate 				{
573*0Sstevel@tonic-gate 					continue;
574*0Sstevel@tonic-gate 				}
575*0Sstevel@tonic-gate 				if (*string == '\0')
576*0Sstevel@tonic-gate 				{
577*0Sstevel@tonic-gate 					break;
578*0Sstevel@tonic-gate 				}
579*0Sstevel@tonic-gate 				if (match("block"))
580*0Sstevel@tonic-gate 				{
581*0Sstevel@tonic-gate 					conv = BLOCK;
582*0Sstevel@tonic-gate 					continue;
583*0Sstevel@tonic-gate 				}
584*0Sstevel@tonic-gate 				if (match("unblock"))
585*0Sstevel@tonic-gate 				{
586*0Sstevel@tonic-gate 					conv = UNBLOCK;
587*0Sstevel@tonic-gate 					continue;
588*0Sstevel@tonic-gate 				}
589*0Sstevel@tonic-gate 
590*0Sstevel@tonic-gate 				/* ebcdicb, ibmb, and asciib must precede */
591*0Sstevel@tonic-gate 				/* ebcdic, ibm, and ascii in this test */
592*0Sstevel@tonic-gate 
593*0Sstevel@tonic-gate 				if (match("ebcdicb"))
594*0Sstevel@tonic-gate 				{
595*0Sstevel@tonic-gate 					conv = EBCDIC;
596*0Sstevel@tonic-gate 					trantype = BSDXLATE;
597*0Sstevel@tonic-gate 					continue;
598*0Sstevel@tonic-gate 				}
599*0Sstevel@tonic-gate 				if (match("ibmb"))
600*0Sstevel@tonic-gate 				{
601*0Sstevel@tonic-gate 					conv = IBM;
602*0Sstevel@tonic-gate 					trantype = BSDXLATE;
603*0Sstevel@tonic-gate 					continue;
604*0Sstevel@tonic-gate 				}
605*0Sstevel@tonic-gate 				if (match("asciib"))
606*0Sstevel@tonic-gate 				{
607*0Sstevel@tonic-gate 					conv = ASCII;
608*0Sstevel@tonic-gate 					trantype = BSDXLATE;
609*0Sstevel@tonic-gate 					continue;
610*0Sstevel@tonic-gate 				}
611*0Sstevel@tonic-gate 				if (match("ebcdic"))
612*0Sstevel@tonic-gate 				{
613*0Sstevel@tonic-gate 					conv = EBCDIC;
614*0Sstevel@tonic-gate 					trantype = SVR4XLATE;
615*0Sstevel@tonic-gate 					continue;
616*0Sstevel@tonic-gate 				}
617*0Sstevel@tonic-gate 				if (match("ibm"))
618*0Sstevel@tonic-gate 				{
619*0Sstevel@tonic-gate 					conv = IBM;
620*0Sstevel@tonic-gate 					trantype = SVR4XLATE;
621*0Sstevel@tonic-gate 					continue;
622*0Sstevel@tonic-gate 				}
623*0Sstevel@tonic-gate 				if (match("ascii"))
624*0Sstevel@tonic-gate 				{
625*0Sstevel@tonic-gate 					conv = ASCII;
626*0Sstevel@tonic-gate 					trantype = SVR4XLATE;
627*0Sstevel@tonic-gate 					continue;
628*0Sstevel@tonic-gate 				}
629*0Sstevel@tonic-gate 				if (match("lcase"))
630*0Sstevel@tonic-gate 				{
631*0Sstevel@tonic-gate 					cflag |= LCASE;
632*0Sstevel@tonic-gate 					continue;
633*0Sstevel@tonic-gate 				}
634*0Sstevel@tonic-gate 				if (match("ucase"))
635*0Sstevel@tonic-gate 				{
636*0Sstevel@tonic-gate 					cflag |= UCASE;
637*0Sstevel@tonic-gate 					continue;
638*0Sstevel@tonic-gate 				}
639*0Sstevel@tonic-gate 				if (match("swab"))
640*0Sstevel@tonic-gate 				{
641*0Sstevel@tonic-gate 					cflag |= SWAB;
642*0Sstevel@tonic-gate 					continue;
643*0Sstevel@tonic-gate 				}
644*0Sstevel@tonic-gate 				if (match("noerror"))
645*0Sstevel@tonic-gate 				{
646*0Sstevel@tonic-gate 					cflag |= NERR;
647*0Sstevel@tonic-gate 					continue;
648*0Sstevel@tonic-gate 				}
649*0Sstevel@tonic-gate 				if (match("notrunc"))
650*0Sstevel@tonic-gate 				{
651*0Sstevel@tonic-gate 					trunc = 0;
652*0Sstevel@tonic-gate 					continue;
653*0Sstevel@tonic-gate 				}
654*0Sstevel@tonic-gate 				if (match("sync"))
655*0Sstevel@tonic-gate 				{
656*0Sstevel@tonic-gate 					cflag |= SYNC;
657*0Sstevel@tonic-gate 					continue;
658*0Sstevel@tonic-gate 				}
659*0Sstevel@tonic-gate 				goto badarg;
660*0Sstevel@tonic-gate 			}
661*0Sstevel@tonic-gate 			continue;
662*0Sstevel@tonic-gate 		}
663*0Sstevel@tonic-gate 		badarg:
664*0Sstevel@tonic-gate 		(void) fprintf(stderr, "dd: %s \"%s\"\n",
665*0Sstevel@tonic-gate 			gettext("bad argument:"), string);
666*0Sstevel@tonic-gate 		exit(2);
667*0Sstevel@tonic-gate 	}
668*0Sstevel@tonic-gate 
669*0Sstevel@tonic-gate 	/* Perform consistency checks on options, decode strange conventions */
670*0Sstevel@tonic-gate 
671*0Sstevel@tonic-gate 	if (bs)
672*0Sstevel@tonic-gate 	{
673*0Sstevel@tonic-gate 		ibs = obs = bs;
674*0Sstevel@tonic-gate 	}
675*0Sstevel@tonic-gate 	if ((ibs == 0) || (obs == 0))
676*0Sstevel@tonic-gate 	{
677*0Sstevel@tonic-gate 		(void) fprintf(stderr, "dd: %s\n",
678*0Sstevel@tonic-gate 			gettext("buffer sizes cannot be zero"));
679*0Sstevel@tonic-gate 		exit(2);
680*0Sstevel@tonic-gate 	}
681*0Sstevel@tonic-gate 	if (conv == COPY)
682*0Sstevel@tonic-gate 	{
683*0Sstevel@tonic-gate 		if ((bs == 0) || (cflag&(LCASE|UCASE)))
684*0Sstevel@tonic-gate 		{
685*0Sstevel@tonic-gate 			conv = REBLOCK;
686*0Sstevel@tonic-gate 		}
687*0Sstevel@tonic-gate 	}
688*0Sstevel@tonic-gate 	if (cbs == 0)
689*0Sstevel@tonic-gate 	{
690*0Sstevel@tonic-gate 		switch (conv)
691*0Sstevel@tonic-gate 		{
692*0Sstevel@tonic-gate 		case BLOCK:
693*0Sstevel@tonic-gate 		case UNBLOCK:
694*0Sstevel@tonic-gate 			conv = REBLOCK;
695*0Sstevel@tonic-gate 			break;
696*0Sstevel@tonic-gate 
697*0Sstevel@tonic-gate 		case ASCII:
698*0Sstevel@tonic-gate 			conv = NBASCII;
699*0Sstevel@tonic-gate 			break;
700*0Sstevel@tonic-gate 
701*0Sstevel@tonic-gate 		case EBCDIC:
702*0Sstevel@tonic-gate 			conv = NBEBCDIC;
703*0Sstevel@tonic-gate 			break;
704*0Sstevel@tonic-gate 
705*0Sstevel@tonic-gate 		case IBM:
706*0Sstevel@tonic-gate 			conv = NBIBM;
707*0Sstevel@tonic-gate 			break;
708*0Sstevel@tonic-gate 		}
709*0Sstevel@tonic-gate 	}
710*0Sstevel@tonic-gate 
711*0Sstevel@tonic-gate 	/* Expand options into lower and upper case versions if necessary */
712*0Sstevel@tonic-gate 
713*0Sstevel@tonic-gate 	switch (conv)
714*0Sstevel@tonic-gate 	{
715*0Sstevel@tonic-gate 	case REBLOCK:
716*0Sstevel@tonic-gate 		if (cflag&LCASE)
717*0Sstevel@tonic-gate 			conv = LCREBLOCK;
718*0Sstevel@tonic-gate 		else if (cflag&UCASE)
719*0Sstevel@tonic-gate 			conv = UCREBLOCK;
720*0Sstevel@tonic-gate 		break;
721*0Sstevel@tonic-gate 
722*0Sstevel@tonic-gate 	case UNBLOCK:
723*0Sstevel@tonic-gate 		if (cflag&LCASE)
724*0Sstevel@tonic-gate 			conv = LCUNBLOCK;
725*0Sstevel@tonic-gate 		else if (cflag&UCASE)
726*0Sstevel@tonic-gate 			conv = UCUNBLOCK;
727*0Sstevel@tonic-gate 		break;
728*0Sstevel@tonic-gate 
729*0Sstevel@tonic-gate 	case BLOCK:
730*0Sstevel@tonic-gate 		if (cflag&LCASE)
731*0Sstevel@tonic-gate 			conv = LCBLOCK;
732*0Sstevel@tonic-gate 		else if (cflag&UCASE)
733*0Sstevel@tonic-gate 			conv = UCBLOCK;
734*0Sstevel@tonic-gate 		break;
735*0Sstevel@tonic-gate 
736*0Sstevel@tonic-gate 	case ASCII:
737*0Sstevel@tonic-gate 		if (cflag&LCASE)
738*0Sstevel@tonic-gate 			conv = LCASCII;
739*0Sstevel@tonic-gate 		else if (cflag&UCASE)
740*0Sstevel@tonic-gate 			conv = UCASCII;
741*0Sstevel@tonic-gate 		break;
742*0Sstevel@tonic-gate 
743*0Sstevel@tonic-gate 	case NBASCII:
744*0Sstevel@tonic-gate 		if (cflag&LCASE)
745*0Sstevel@tonic-gate 			conv = LCNBASCII;
746*0Sstevel@tonic-gate 		else if (cflag&UCASE)
747*0Sstevel@tonic-gate 			conv = UCNBASCII;
748*0Sstevel@tonic-gate 		break;
749*0Sstevel@tonic-gate 
750*0Sstevel@tonic-gate 	case EBCDIC:
751*0Sstevel@tonic-gate 		if (cflag&LCASE)
752*0Sstevel@tonic-gate 			conv = LCEBCDIC;
753*0Sstevel@tonic-gate 		else if (cflag&UCASE)
754*0Sstevel@tonic-gate 			conv = UCEBCDIC;
755*0Sstevel@tonic-gate 		break;
756*0Sstevel@tonic-gate 
757*0Sstevel@tonic-gate 	case NBEBCDIC:
758*0Sstevel@tonic-gate 		if (cflag&LCASE)
759*0Sstevel@tonic-gate 			conv = LCNBEBCDIC;
760*0Sstevel@tonic-gate 		else if (cflag&UCASE)
761*0Sstevel@tonic-gate 			conv = UCNBEBCDIC;
762*0Sstevel@tonic-gate 		break;
763*0Sstevel@tonic-gate 
764*0Sstevel@tonic-gate 	case IBM:
765*0Sstevel@tonic-gate 		if (cflag&LCASE)
766*0Sstevel@tonic-gate 			conv = LCIBM;
767*0Sstevel@tonic-gate 		else if (cflag&UCASE)
768*0Sstevel@tonic-gate 			conv = UCIBM;
769*0Sstevel@tonic-gate 		break;
770*0Sstevel@tonic-gate 
771*0Sstevel@tonic-gate 	case NBIBM:
772*0Sstevel@tonic-gate 		if (cflag&LCASE)
773*0Sstevel@tonic-gate 			conv = LCNBIBM;
774*0Sstevel@tonic-gate 		else if (cflag&UCASE)
775*0Sstevel@tonic-gate 			conv = UCNBIBM;
776*0Sstevel@tonic-gate 		break;
777*0Sstevel@tonic-gate 	}
778*0Sstevel@tonic-gate 
779*0Sstevel@tonic-gate 	/* If BSD-compatible translation is selected, change the tables */
780*0Sstevel@tonic-gate 
781*0Sstevel@tonic-gate 	if (trantype == BSDXLATE) {
782*0Sstevel@tonic-gate 		atoe = bsd_atoe;
783*0Sstevel@tonic-gate 		atoibm = bsd_atoibm;
784*0Sstevel@tonic-gate 		etoa = bsd_etoa;
785*0Sstevel@tonic-gate 	}
786*0Sstevel@tonic-gate 	/* Open the input file, or duplicate standard input */
787*0Sstevel@tonic-gate 
788*0Sstevel@tonic-gate 	ibf = -1;
789*0Sstevel@tonic-gate 	if (ifile)
790*0Sstevel@tonic-gate 	{
791*0Sstevel@tonic-gate 		ibf = open(ifile, 0);
792*0Sstevel@tonic-gate 	}
793*0Sstevel@tonic-gate #ifndef STANDALONE
794*0Sstevel@tonic-gate 	else
795*0Sstevel@tonic-gate 	{
796*0Sstevel@tonic-gate 		ifile = "";
797*0Sstevel@tonic-gate 		ibf = dup(0);
798*0Sstevel@tonic-gate 	}
799*0Sstevel@tonic-gate #endif
800*0Sstevel@tonic-gate 	if (ibf == -1)
801*0Sstevel@tonic-gate 	{
802*0Sstevel@tonic-gate 		(void) fprintf(stderr, "dd: %s: ", ifile);
803*0Sstevel@tonic-gate 		perror("open");
804*0Sstevel@tonic-gate 		exit(2);
805*0Sstevel@tonic-gate 	}
806*0Sstevel@tonic-gate 
807*0Sstevel@tonic-gate 	/* Open the output file, or duplicate standard output */
808*0Sstevel@tonic-gate 
809*0Sstevel@tonic-gate 	obf = -1;
810*0Sstevel@tonic-gate 	if (ofile)
811*0Sstevel@tonic-gate 	{
812*0Sstevel@tonic-gate 		if (trunc == 0)	/* do not truncate output file */
813*0Sstevel@tonic-gate 			obf = open(ofile, (O_WRONLY|O_CREAT),
814*0Sstevel@tonic-gate 			(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
815*0Sstevel@tonic-gate 		else if (oseekn && (trunc == 1))
816*0Sstevel@tonic-gate 		{
817*0Sstevel@tonic-gate 			obf = open(ofile, O_WRONLY|O_CREAT,
818*0Sstevel@tonic-gate 			(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
819*0Sstevel@tonic-gate 			if (obf == -1)
820*0Sstevel@tonic-gate 			{
821*0Sstevel@tonic-gate 				(void) fprintf(stderr, "dd: %s: ", ofile);
822*0Sstevel@tonic-gate 				perror("open");
823*0Sstevel@tonic-gate 				exit(2);
824*0Sstevel@tonic-gate 			}
825*0Sstevel@tonic-gate 			(void) fstat(obf, &file_stat);
826*0Sstevel@tonic-gate 			if (((file_stat.st_mode & S_IFMT) == S_IFREG) &&
827*0Sstevel@tonic-gate 			    (ftruncate(obf, (((off_t)oseekn) * ((off_t)obs)))
828*0Sstevel@tonic-gate 				== -1))
829*0Sstevel@tonic-gate 			{
830*0Sstevel@tonic-gate 				perror("ftruncate");
831*0Sstevel@tonic-gate 				exit(2);
832*0Sstevel@tonic-gate 			}
833*0Sstevel@tonic-gate 		}
834*0Sstevel@tonic-gate 		else
835*0Sstevel@tonic-gate 			obf = creat(ofile,
836*0Sstevel@tonic-gate 			(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
837*0Sstevel@tonic-gate 	}
838*0Sstevel@tonic-gate #ifndef STANDALONE
839*0Sstevel@tonic-gate 	else
840*0Sstevel@tonic-gate 	{
841*0Sstevel@tonic-gate 		ofile = "";
842*0Sstevel@tonic-gate 		obf = dup(1);
843*0Sstevel@tonic-gate 	}
844*0Sstevel@tonic-gate #endif
845*0Sstevel@tonic-gate 	if (obf == -1)
846*0Sstevel@tonic-gate 	{
847*0Sstevel@tonic-gate 		(void) fprintf(stderr, "dd: %s: ", ofile);
848*0Sstevel@tonic-gate 		perror("open");
849*0Sstevel@tonic-gate 		exit(2);
850*0Sstevel@tonic-gate 	}
851*0Sstevel@tonic-gate 
852*0Sstevel@tonic-gate 	/* Expand memory to get an input buffer */
853*0Sstevel@tonic-gate 
854*0Sstevel@tonic-gate 	ibuf = (unsigned char *)valloc(ibs + 10);
855*0Sstevel@tonic-gate 
856*0Sstevel@tonic-gate 	/* If no conversions, the input buffer is the output buffer */
857*0Sstevel@tonic-gate 
858*0Sstevel@tonic-gate 	if (conv == COPY)
859*0Sstevel@tonic-gate 	{
860*0Sstevel@tonic-gate 		obuf = ibuf;
861*0Sstevel@tonic-gate 	}
862*0Sstevel@tonic-gate 
863*0Sstevel@tonic-gate 	/* Expand memory to get an output buffer. Leave enough room at the */
864*0Sstevel@tonic-gate 	/* end to convert a logical record when doing block conversions. */
865*0Sstevel@tonic-gate 
866*0Sstevel@tonic-gate 	else
867*0Sstevel@tonic-gate 	{
868*0Sstevel@tonic-gate 		obuf = (unsigned char *)valloc(obs + cbs + 10);
869*0Sstevel@tonic-gate 	}
870*0Sstevel@tonic-gate 	if ((ibuf == (unsigned char *)NULL) || (obuf == (unsigned char *)NULL))
871*0Sstevel@tonic-gate 	{
872*0Sstevel@tonic-gate 		(void) fprintf(stderr,
873*0Sstevel@tonic-gate 			"dd: %s\n", gettext("not enough memory"));
874*0Sstevel@tonic-gate 		exit(2);
875*0Sstevel@tonic-gate 	}
876*0Sstevel@tonic-gate 
877*0Sstevel@tonic-gate 	/* Enable a statistics message on SIGINT */
878*0Sstevel@tonic-gate 
879*0Sstevel@tonic-gate #ifndef STANDALONE
880*0Sstevel@tonic-gate 	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
881*0Sstevel@tonic-gate 	{
882*0Sstevel@tonic-gate 		(void) signal(SIGINT, term);
883*0Sstevel@tonic-gate 	}
884*0Sstevel@tonic-gate #endif
885*0Sstevel@tonic-gate 	/* Skip input blocks */
886*0Sstevel@tonic-gate 
887*0Sstevel@tonic-gate 	while (skip)
888*0Sstevel@tonic-gate 	{
889*0Sstevel@tonic-gate 		ibc = read(ibf, (char *)ibuf, ibs);
890*0Sstevel@tonic-gate 		if (ibc == (unsigned)-1)
891*0Sstevel@tonic-gate 		{
892*0Sstevel@tonic-gate 			if (++nbad > BADLIMIT)
893*0Sstevel@tonic-gate 			{
894*0Sstevel@tonic-gate 				(void) fprintf(stderr, "dd: %s\n",
895*0Sstevel@tonic-gate 					gettext("skip failed"));
896*0Sstevel@tonic-gate 				exit(2);
897*0Sstevel@tonic-gate 			}
898*0Sstevel@tonic-gate 			else
899*0Sstevel@tonic-gate 			{
900*0Sstevel@tonic-gate 				perror("read");
901*0Sstevel@tonic-gate 			}
902*0Sstevel@tonic-gate 		}
903*0Sstevel@tonic-gate 		else
904*0Sstevel@tonic-gate 		{
905*0Sstevel@tonic-gate 			if (ibc == 0)
906*0Sstevel@tonic-gate 			{
907*0Sstevel@tonic-gate 				(void) fprintf(stderr, "dd: %s\n",
908*0Sstevel@tonic-gate 				gettext("cannot skip past end-of-file"));
909*0Sstevel@tonic-gate 				exit(3);
910*0Sstevel@tonic-gate 			}
911*0Sstevel@tonic-gate 			else
912*0Sstevel@tonic-gate 			{
913*0Sstevel@tonic-gate 				nbad = 0;
914*0Sstevel@tonic-gate 			}
915*0Sstevel@tonic-gate 		}
916*0Sstevel@tonic-gate 		skip--;
917*0Sstevel@tonic-gate 	}
918*0Sstevel@tonic-gate 
919*0Sstevel@tonic-gate 	/* Seek past input blocks */
920*0Sstevel@tonic-gate 
921*0Sstevel@tonic-gate 	if (iseekn && lseek(ibf, (((off_t)iseekn) * ((off_t)ibs)), 1) == -1)
922*0Sstevel@tonic-gate 	{
923*0Sstevel@tonic-gate 		perror("lseek");
924*0Sstevel@tonic-gate 		exit(2);
925*0Sstevel@tonic-gate 	}
926*0Sstevel@tonic-gate 
927*0Sstevel@tonic-gate 	/* Seek past output blocks */
928*0Sstevel@tonic-gate 
929*0Sstevel@tonic-gate 	if (oseekn && lseek(obf, (((off_t)oseekn) * ((off_t)obs)), 1) == -1)
930*0Sstevel@tonic-gate 	{
931*0Sstevel@tonic-gate 		perror("lseek");
932*0Sstevel@tonic-gate 		exit(2);
933*0Sstevel@tonic-gate 	}
934*0Sstevel@tonic-gate 
935*0Sstevel@tonic-gate 	/* Initialize all buffer pointers */
936*0Sstevel@tonic-gate 
937*0Sstevel@tonic-gate 	skipf = 0;	/* not skipping an input line */
938*0Sstevel@tonic-gate 	ibc = 0;	/* no input characters yet */
939*0Sstevel@tonic-gate 	obc = 0;	/* no output characters yet */
940*0Sstevel@tonic-gate 	cbc = 0;	/* the conversion buffer is empty */
941*0Sstevel@tonic-gate 	op = obuf;	/* point to the output buffer */
942*0Sstevel@tonic-gate 
943*0Sstevel@tonic-gate 	/* Read and convert input blocks until end of file(s) */
944*0Sstevel@tonic-gate 
945*0Sstevel@tonic-gate 	for (;;)
946*0Sstevel@tonic-gate 	{
947*0Sstevel@tonic-gate 		if ((count == 0) || (nifr+nipr < count))
948*0Sstevel@tonic-gate 		{
949*0Sstevel@tonic-gate 		/* If proceed on error is enabled, zero the input buffer */
950*0Sstevel@tonic-gate 
951*0Sstevel@tonic-gate 			if (cflag&NERR)
952*0Sstevel@tonic-gate 			{
953*0Sstevel@tonic-gate 				ip = ibuf + ibs;
954*0Sstevel@tonic-gate 				c = ibs;
955*0Sstevel@tonic-gate 				if (c & 1)	/* if the size is odd, */
956*0Sstevel@tonic-gate 				{
957*0Sstevel@tonic-gate 					*--ip = 0;	/* clear the odd byte */
958*0Sstevel@tonic-gate 				}
959*0Sstevel@tonic-gate 				if (c >>= 1)		/* divide by two */
960*0Sstevel@tonic-gate 				{
961*0Sstevel@tonic-gate 					do {	/* clear two at a time */
962*0Sstevel@tonic-gate 						*--ip = 0;
963*0Sstevel@tonic-gate 						*--ip = 0;
964*0Sstevel@tonic-gate 					} while (--c);
965*0Sstevel@tonic-gate 				}
966*0Sstevel@tonic-gate 			}
967*0Sstevel@tonic-gate 
968*0Sstevel@tonic-gate 			/* Read the next input block */
969*0Sstevel@tonic-gate 
970*0Sstevel@tonic-gate 			ibc = read(ibf, (char *)ibuf, ibs);
971*0Sstevel@tonic-gate 
972*0Sstevel@tonic-gate 			/* Process input errors */
973*0Sstevel@tonic-gate 
974*0Sstevel@tonic-gate 			if (ibc == (unsigned)-1)
975*0Sstevel@tonic-gate 			{
976*0Sstevel@tonic-gate 				perror("read");
977*0Sstevel@tonic-gate 				if (((cflag&NERR) == 0) || (++nbad > BADLIMIT))
978*0Sstevel@tonic-gate 				{
979*0Sstevel@tonic-gate 					while (obc)
980*0Sstevel@tonic-gate 					{
981*0Sstevel@tonic-gate 						(void) flsh();
982*0Sstevel@tonic-gate 					}
983*0Sstevel@tonic-gate 					term(2);
984*0Sstevel@tonic-gate 				}
985*0Sstevel@tonic-gate 				else
986*0Sstevel@tonic-gate 				{
987*0Sstevel@tonic-gate 					stats();
988*0Sstevel@tonic-gate 					ibc = ibs; /* assume a full block */
989*0Sstevel@tonic-gate 				}
990*0Sstevel@tonic-gate 			}
991*0Sstevel@tonic-gate 			else
992*0Sstevel@tonic-gate 			{
993*0Sstevel@tonic-gate 				nbad = 0;
994*0Sstevel@tonic-gate 			}
995*0Sstevel@tonic-gate 		}
996*0Sstevel@tonic-gate 
997*0Sstevel@tonic-gate 		/* Record count satisfied, simulate end of file */
998*0Sstevel@tonic-gate 
999*0Sstevel@tonic-gate 		else
1000*0Sstevel@tonic-gate 		{
1001*0Sstevel@tonic-gate 			ibc = 0;
1002*0Sstevel@tonic-gate 			files = 1;
1003*0Sstevel@tonic-gate 		}
1004*0Sstevel@tonic-gate 
1005*0Sstevel@tonic-gate 		/* Process end of file */
1006*0Sstevel@tonic-gate 
1007*0Sstevel@tonic-gate 		if (ibc == 0)
1008*0Sstevel@tonic-gate 		{
1009*0Sstevel@tonic-gate 			switch (conv)
1010*0Sstevel@tonic-gate 			{
1011*0Sstevel@tonic-gate 			case UNBLOCK:
1012*0Sstevel@tonic-gate 			case LCUNBLOCK:
1013*0Sstevel@tonic-gate 			case UCUNBLOCK:
1014*0Sstevel@tonic-gate 			case ASCII:
1015*0Sstevel@tonic-gate 			case LCASCII:
1016*0Sstevel@tonic-gate 			case UCASCII:
1017*0Sstevel@tonic-gate 
1018*0Sstevel@tonic-gate 				/* Trim trailing blanks from the last line */
1019*0Sstevel@tonic-gate 
1020*0Sstevel@tonic-gate 				if ((c = cbc) != 0)
1021*0Sstevel@tonic-gate 				{
1022*0Sstevel@tonic-gate 					do {
1023*0Sstevel@tonic-gate 						if ((*--op) != ' ')
1024*0Sstevel@tonic-gate 						{
1025*0Sstevel@tonic-gate 							op++;
1026*0Sstevel@tonic-gate 							break;
1027*0Sstevel@tonic-gate 						}
1028*0Sstevel@tonic-gate 					} while (--c);
1029*0Sstevel@tonic-gate 					*op++ = '\n';
1030*0Sstevel@tonic-gate 					obc -= cbc - c - 1;
1031*0Sstevel@tonic-gate 					cbc = 0;
1032*0Sstevel@tonic-gate 
1033*0Sstevel@tonic-gate 					/* Flush the output buffer if full */
1034*0Sstevel@tonic-gate 
1035*0Sstevel@tonic-gate 					while (obc >= obs)
1036*0Sstevel@tonic-gate 					{
1037*0Sstevel@tonic-gate 						op = flsh();
1038*0Sstevel@tonic-gate 					}
1039*0Sstevel@tonic-gate 				}
1040*0Sstevel@tonic-gate 				break;
1041*0Sstevel@tonic-gate 
1042*0Sstevel@tonic-gate 			case BLOCK:
1043*0Sstevel@tonic-gate 			case LCBLOCK:
1044*0Sstevel@tonic-gate 			case UCBLOCK:
1045*0Sstevel@tonic-gate 			case EBCDIC:
1046*0Sstevel@tonic-gate 			case LCEBCDIC:
1047*0Sstevel@tonic-gate 			case UCEBCDIC:
1048*0Sstevel@tonic-gate 			case IBM:
1049*0Sstevel@tonic-gate 			case LCIBM:
1050*0Sstevel@tonic-gate 			case UCIBM:
1051*0Sstevel@tonic-gate 
1052*0Sstevel@tonic-gate 			/* Pad trailing blanks if the last line is short */
1053*0Sstevel@tonic-gate 
1054*0Sstevel@tonic-gate 				if (cbc)
1055*0Sstevel@tonic-gate 				{
1056*0Sstevel@tonic-gate 					obc += c = cbs - cbc;
1057*0Sstevel@tonic-gate 					cbc = 0;
1058*0Sstevel@tonic-gate 					if (c > 0)
1059*0Sstevel@tonic-gate 					{
1060*0Sstevel@tonic-gate 					/* Use the right kind of blank */
1061*0Sstevel@tonic-gate 
1062*0Sstevel@tonic-gate 						switch (conv)
1063*0Sstevel@tonic-gate 						{
1064*0Sstevel@tonic-gate 						case BLOCK:
1065*0Sstevel@tonic-gate 						case LCBLOCK:
1066*0Sstevel@tonic-gate 						case UCBLOCK:
1067*0Sstevel@tonic-gate 							ic = ' ';
1068*0Sstevel@tonic-gate 							break;
1069*0Sstevel@tonic-gate 
1070*0Sstevel@tonic-gate 						case EBCDIC:
1071*0Sstevel@tonic-gate 						case LCEBCDIC:
1072*0Sstevel@tonic-gate 						case UCEBCDIC:
1073*0Sstevel@tonic-gate 							ic = atoe[' '];
1074*0Sstevel@tonic-gate 							break;
1075*0Sstevel@tonic-gate 
1076*0Sstevel@tonic-gate 						case IBM:
1077*0Sstevel@tonic-gate 						case LCIBM:
1078*0Sstevel@tonic-gate 						case UCIBM:
1079*0Sstevel@tonic-gate 							ic = atoibm[' '];
1080*0Sstevel@tonic-gate 							break;
1081*0Sstevel@tonic-gate 						}
1082*0Sstevel@tonic-gate 
1083*0Sstevel@tonic-gate 						/* Pad with trailing blanks */
1084*0Sstevel@tonic-gate 
1085*0Sstevel@tonic-gate 						do {
1086*0Sstevel@tonic-gate 							*op++ = ic;
1087*0Sstevel@tonic-gate 						} while (--c);
1088*0Sstevel@tonic-gate 					}
1089*0Sstevel@tonic-gate 				}
1090*0Sstevel@tonic-gate 
1091*0Sstevel@tonic-gate 
1092*0Sstevel@tonic-gate 				/* Flush the output buffer if full */
1093*0Sstevel@tonic-gate 
1094*0Sstevel@tonic-gate 				while (obc >= obs)
1095*0Sstevel@tonic-gate 				{
1096*0Sstevel@tonic-gate 					op = flsh();
1097*0Sstevel@tonic-gate 				}
1098*0Sstevel@tonic-gate 				break;
1099*0Sstevel@tonic-gate 			}
1100*0Sstevel@tonic-gate 
1101*0Sstevel@tonic-gate 			/* If no more files to read, flush the output buffer */
1102*0Sstevel@tonic-gate 
1103*0Sstevel@tonic-gate 			if (--files <= 0)
1104*0Sstevel@tonic-gate 			{
1105*0Sstevel@tonic-gate 				(void) flsh();
1106*0Sstevel@tonic-gate 				if ((close(obf) != 0) || (fclose(stdout) != 0))
1107*0Sstevel@tonic-gate 				{
1108*0Sstevel@tonic-gate 					perror(gettext("dd: close error"));
1109*0Sstevel@tonic-gate 					exit(2);
1110*0Sstevel@tonic-gate 				}
1111*0Sstevel@tonic-gate 				term(0);	/* successful exit */
1112*0Sstevel@tonic-gate 			}
1113*0Sstevel@tonic-gate 			else
1114*0Sstevel@tonic-gate 			{
1115*0Sstevel@tonic-gate 				continue;	/* read the next file */
1116*0Sstevel@tonic-gate 			}
1117*0Sstevel@tonic-gate 		}
1118*0Sstevel@tonic-gate 
1119*0Sstevel@tonic-gate 		/* Normal read, check for special cases */
1120*0Sstevel@tonic-gate 
1121*0Sstevel@tonic-gate 		else if (ibc == ibs)
1122*0Sstevel@tonic-gate 		{
1123*0Sstevel@tonic-gate 			nifr++;		/* count another full input record */
1124*0Sstevel@tonic-gate 		}
1125*0Sstevel@tonic-gate 		else
1126*0Sstevel@tonic-gate 		{
1127*0Sstevel@tonic-gate 			nipr++;		/* count a partial input record */
1128*0Sstevel@tonic-gate 
1129*0Sstevel@tonic-gate 			/* If `sync' enabled, pad nulls */
1130*0Sstevel@tonic-gate 
1131*0Sstevel@tonic-gate 			if ((cflag&SYNC) && ((cflag&NERR) == 0))
1132*0Sstevel@tonic-gate 			{
1133*0Sstevel@tonic-gate 				c = ibs - ibc;
1134*0Sstevel@tonic-gate 				ip = ibuf + ibs;
1135*0Sstevel@tonic-gate 				do {
1136*0Sstevel@tonic-gate 				if ((conv == BLOCK) || (conv == UNBLOCK))
1137*0Sstevel@tonic-gate 					*--ip = ' ';
1138*0Sstevel@tonic-gate 				else
1139*0Sstevel@tonic-gate 					*--ip = '\0';
1140*0Sstevel@tonic-gate 				} while (--c);
1141*0Sstevel@tonic-gate 				ibc = ibs;
1142*0Sstevel@tonic-gate 			}
1143*0Sstevel@tonic-gate 		}
1144*0Sstevel@tonic-gate 
1145*0Sstevel@tonic-gate 		/* Swap the bytes in the input buffer if necessary */
1146*0Sstevel@tonic-gate 
1147*0Sstevel@tonic-gate 		if (cflag&SWAB)
1148*0Sstevel@tonic-gate 		{
1149*0Sstevel@tonic-gate 			ip = ibuf;
1150*0Sstevel@tonic-gate 			if (ibc & 1)	/* if the byte count is odd, */
1151*0Sstevel@tonic-gate 			{
1152*0Sstevel@tonic-gate 				ip[ibc] = 0;  /* make it even, pad with zero */
1153*0Sstevel@tonic-gate 			}
1154*0Sstevel@tonic-gate 			c = ibc >> 1;	/* compute the pair count */
1155*0Sstevel@tonic-gate 			do {
1156*0Sstevel@tonic-gate 				ic = *ip++;
1157*0Sstevel@tonic-gate 				ip[-1] = *ip;
1158*0Sstevel@tonic-gate 				*ip++ = ic;
1159*0Sstevel@tonic-gate 			} while (--c);		/* do two bytes at a time */
1160*0Sstevel@tonic-gate 		}
1161*0Sstevel@tonic-gate 
1162*0Sstevel@tonic-gate 		/* Select the appropriate conversion loop */
1163*0Sstevel@tonic-gate 
1164*0Sstevel@tonic-gate 		ip = ibuf;
1165*0Sstevel@tonic-gate 		switch (conv)
1166*0Sstevel@tonic-gate 		{
1167*0Sstevel@tonic-gate 
1168*0Sstevel@tonic-gate 		/* Simple copy: no conversion, preserve the input block size */
1169*0Sstevel@tonic-gate 
1170*0Sstevel@tonic-gate 		case COPY:
1171*0Sstevel@tonic-gate 			obc = ibc;
1172*0Sstevel@tonic-gate 			(void) flsh();
1173*0Sstevel@tonic-gate 			break;
1174*0Sstevel@tonic-gate 
1175*0Sstevel@tonic-gate 		/* Simple copy: pack all output into equal sized blocks */
1176*0Sstevel@tonic-gate 
1177*0Sstevel@tonic-gate 		case REBLOCK:
1178*0Sstevel@tonic-gate 		case LCREBLOCK:
1179*0Sstevel@tonic-gate 		case UCREBLOCK:
1180*0Sstevel@tonic-gate 		case NBASCII:
1181*0Sstevel@tonic-gate 		case LCNBASCII:
1182*0Sstevel@tonic-gate 		case UCNBASCII:
1183*0Sstevel@tonic-gate 		case NBEBCDIC:
1184*0Sstevel@tonic-gate 		case LCNBEBCDIC:
1185*0Sstevel@tonic-gate 		case UCNBEBCDIC:
1186*0Sstevel@tonic-gate 		case NBIBM:
1187*0Sstevel@tonic-gate 		case LCNBIBM:
1188*0Sstevel@tonic-gate 		case UCNBIBM:
1189*0Sstevel@tonic-gate 			while ((c = ibc) != 0)
1190*0Sstevel@tonic-gate 			{
1191*0Sstevel@tonic-gate 				if (c > (obs - obc))
1192*0Sstevel@tonic-gate 				{
1193*0Sstevel@tonic-gate 					c = obs - obc;
1194*0Sstevel@tonic-gate 				}
1195*0Sstevel@tonic-gate 				ibc -= c;
1196*0Sstevel@tonic-gate 				obc += c;
1197*0Sstevel@tonic-gate 				switch (conv)
1198*0Sstevel@tonic-gate 				{
1199*0Sstevel@tonic-gate 				case REBLOCK:
1200*0Sstevel@tonic-gate 					do {
1201*0Sstevel@tonic-gate 						*op++ = *ip++;
1202*0Sstevel@tonic-gate 					} while (--c);
1203*0Sstevel@tonic-gate 					break;
1204*0Sstevel@tonic-gate 
1205*0Sstevel@tonic-gate 				case LCREBLOCK:
1206*0Sstevel@tonic-gate 					do {
1207*0Sstevel@tonic-gate 						*op++ = utol[*ip++];
1208*0Sstevel@tonic-gate 					} while (--c);
1209*0Sstevel@tonic-gate 					break;
1210*0Sstevel@tonic-gate 
1211*0Sstevel@tonic-gate 				case UCREBLOCK:
1212*0Sstevel@tonic-gate 					do {
1213*0Sstevel@tonic-gate 						*op++ = ltou[*ip++];
1214*0Sstevel@tonic-gate 					} while (--c);
1215*0Sstevel@tonic-gate 					break;
1216*0Sstevel@tonic-gate 
1217*0Sstevel@tonic-gate 				case NBASCII:
1218*0Sstevel@tonic-gate 					do {
1219*0Sstevel@tonic-gate 						*op++ = etoa[*ip++];
1220*0Sstevel@tonic-gate 					} while (--c);
1221*0Sstevel@tonic-gate 					break;
1222*0Sstevel@tonic-gate 
1223*0Sstevel@tonic-gate 				case LCNBASCII:
1224*0Sstevel@tonic-gate 					do {
1225*0Sstevel@tonic-gate 						*op++ = utol[etoa[*ip++]];
1226*0Sstevel@tonic-gate 					} while (--c);
1227*0Sstevel@tonic-gate 					break;
1228*0Sstevel@tonic-gate 
1229*0Sstevel@tonic-gate 				case UCNBASCII:
1230*0Sstevel@tonic-gate 					do {
1231*0Sstevel@tonic-gate 						*op++ = ltou[etoa[*ip++]];
1232*0Sstevel@tonic-gate 					} while (--c);
1233*0Sstevel@tonic-gate 					break;
1234*0Sstevel@tonic-gate 
1235*0Sstevel@tonic-gate 				case NBEBCDIC:
1236*0Sstevel@tonic-gate 					do {
1237*0Sstevel@tonic-gate 						*op++ = atoe[*ip++];
1238*0Sstevel@tonic-gate 					} while (--c);
1239*0Sstevel@tonic-gate 					break;
1240*0Sstevel@tonic-gate 
1241*0Sstevel@tonic-gate 				case LCNBEBCDIC:
1242*0Sstevel@tonic-gate 					do {
1243*0Sstevel@tonic-gate 						*op++ = atoe[utol[*ip++]];
1244*0Sstevel@tonic-gate 					} while (--c);
1245*0Sstevel@tonic-gate 					break;
1246*0Sstevel@tonic-gate 
1247*0Sstevel@tonic-gate 				case UCNBEBCDIC:
1248*0Sstevel@tonic-gate 					do {
1249*0Sstevel@tonic-gate 						*op++ = atoe[ltou[*ip++]];
1250*0Sstevel@tonic-gate 					} while (--c);
1251*0Sstevel@tonic-gate 					break;
1252*0Sstevel@tonic-gate 
1253*0Sstevel@tonic-gate 				case NBIBM:
1254*0Sstevel@tonic-gate 					do {
1255*0Sstevel@tonic-gate 						*op++ = atoibm[*ip++];
1256*0Sstevel@tonic-gate 					} while (--c);
1257*0Sstevel@tonic-gate 					break;
1258*0Sstevel@tonic-gate 
1259*0Sstevel@tonic-gate 				case LCNBIBM:
1260*0Sstevel@tonic-gate 					do {
1261*0Sstevel@tonic-gate 						*op++ = atoibm[utol[*ip++]];
1262*0Sstevel@tonic-gate 					} while (--c);
1263*0Sstevel@tonic-gate 					break;
1264*0Sstevel@tonic-gate 
1265*0Sstevel@tonic-gate 				case UCNBIBM:
1266*0Sstevel@tonic-gate 					do {
1267*0Sstevel@tonic-gate 						*op++ = atoibm[ltou[*ip++]];
1268*0Sstevel@tonic-gate 					} while (--c);
1269*0Sstevel@tonic-gate 					break;
1270*0Sstevel@tonic-gate 				}
1271*0Sstevel@tonic-gate 				if (obc >= obs)
1272*0Sstevel@tonic-gate 				{
1273*0Sstevel@tonic-gate 					op = flsh();
1274*0Sstevel@tonic-gate 				}
1275*0Sstevel@tonic-gate 			}
1276*0Sstevel@tonic-gate 			break;
1277*0Sstevel@tonic-gate 
1278*0Sstevel@tonic-gate 	/* Convert from blocked records to lines terminated by newline */
1279*0Sstevel@tonic-gate 
1280*0Sstevel@tonic-gate 		case UNBLOCK:
1281*0Sstevel@tonic-gate 		case LCUNBLOCK:
1282*0Sstevel@tonic-gate 		case UCUNBLOCK:
1283*0Sstevel@tonic-gate 		case ASCII:
1284*0Sstevel@tonic-gate 		case LCASCII:
1285*0Sstevel@tonic-gate 		case UCASCII:
1286*0Sstevel@tonic-gate 			while ((c = ibc) != 0)
1287*0Sstevel@tonic-gate 			{
1288*0Sstevel@tonic-gate 				if (c > (cbs - cbc))
1289*0Sstevel@tonic-gate 						/* if more than one record, */
1290*0Sstevel@tonic-gate 				{
1291*0Sstevel@tonic-gate 					c = cbs - cbc;
1292*0Sstevel@tonic-gate 						/* only copy one record */
1293*0Sstevel@tonic-gate 				}
1294*0Sstevel@tonic-gate 				ibc -= c;
1295*0Sstevel@tonic-gate 				cbc += c;
1296*0Sstevel@tonic-gate 				obc += c;
1297*0Sstevel@tonic-gate 				switch (conv)
1298*0Sstevel@tonic-gate 				{
1299*0Sstevel@tonic-gate 				case UNBLOCK:
1300*0Sstevel@tonic-gate 					do {
1301*0Sstevel@tonic-gate 						*op++ = *ip++;
1302*0Sstevel@tonic-gate 					} while (--c);
1303*0Sstevel@tonic-gate 					break;
1304*0Sstevel@tonic-gate 
1305*0Sstevel@tonic-gate 				case LCUNBLOCK:
1306*0Sstevel@tonic-gate 					do {
1307*0Sstevel@tonic-gate 						*op++ = utol[*ip++];
1308*0Sstevel@tonic-gate 					} while (--c);
1309*0Sstevel@tonic-gate 					break;
1310*0Sstevel@tonic-gate 
1311*0Sstevel@tonic-gate 				case UCUNBLOCK:
1312*0Sstevel@tonic-gate 					do {
1313*0Sstevel@tonic-gate 						*op++ = ltou[*ip++];
1314*0Sstevel@tonic-gate 					} while (--c);
1315*0Sstevel@tonic-gate 					break;
1316*0Sstevel@tonic-gate 
1317*0Sstevel@tonic-gate 				case ASCII:
1318*0Sstevel@tonic-gate 					do {
1319*0Sstevel@tonic-gate 						*op++ = etoa[*ip++];
1320*0Sstevel@tonic-gate 					} while (--c);
1321*0Sstevel@tonic-gate 					break;
1322*0Sstevel@tonic-gate 
1323*0Sstevel@tonic-gate 				case LCASCII:
1324*0Sstevel@tonic-gate 					do {
1325*0Sstevel@tonic-gate 						*op++ = utol[etoa[*ip++]];
1326*0Sstevel@tonic-gate 					} while (--c);
1327*0Sstevel@tonic-gate 					break;
1328*0Sstevel@tonic-gate 
1329*0Sstevel@tonic-gate 				case UCASCII:
1330*0Sstevel@tonic-gate 					do {
1331*0Sstevel@tonic-gate 						*op++ = ltou[etoa[*ip++]];
1332*0Sstevel@tonic-gate 					} while (--c);
1333*0Sstevel@tonic-gate 					break;
1334*0Sstevel@tonic-gate 				}
1335*0Sstevel@tonic-gate 
1336*0Sstevel@tonic-gate 				/* Trim trailing blanks if the line is full */
1337*0Sstevel@tonic-gate 
1338*0Sstevel@tonic-gate 				if (cbc == cbs)
1339*0Sstevel@tonic-gate 				{
1340*0Sstevel@tonic-gate 					c = cbs; /* `do - while' is usually */
1341*0Sstevel@tonic-gate 					do {		/* faster than `for' */
1342*0Sstevel@tonic-gate 						if ((*--op) != ' ')
1343*0Sstevel@tonic-gate 						{
1344*0Sstevel@tonic-gate 							op++;
1345*0Sstevel@tonic-gate 							break;
1346*0Sstevel@tonic-gate 						}
1347*0Sstevel@tonic-gate 					} while (--c);
1348*0Sstevel@tonic-gate 					*op++ = '\n';
1349*0Sstevel@tonic-gate 					obc -= cbs - c - 1;
1350*0Sstevel@tonic-gate 					cbc = 0;
1351*0Sstevel@tonic-gate 
1352*0Sstevel@tonic-gate 					/* Flush the output buffer if full */
1353*0Sstevel@tonic-gate 
1354*0Sstevel@tonic-gate 					while (obc >= obs)
1355*0Sstevel@tonic-gate 					{
1356*0Sstevel@tonic-gate 						op = flsh();
1357*0Sstevel@tonic-gate 					}
1358*0Sstevel@tonic-gate 				}
1359*0Sstevel@tonic-gate 			}
1360*0Sstevel@tonic-gate 			break;
1361*0Sstevel@tonic-gate 
1362*0Sstevel@tonic-gate 		/* Convert to blocked records */
1363*0Sstevel@tonic-gate 
1364*0Sstevel@tonic-gate 		case BLOCK:
1365*0Sstevel@tonic-gate 		case LCBLOCK:
1366*0Sstevel@tonic-gate 		case UCBLOCK:
1367*0Sstevel@tonic-gate 		case EBCDIC:
1368*0Sstevel@tonic-gate 		case LCEBCDIC:
1369*0Sstevel@tonic-gate 		case UCEBCDIC:
1370*0Sstevel@tonic-gate 		case IBM:
1371*0Sstevel@tonic-gate 		case LCIBM:
1372*0Sstevel@tonic-gate 		case UCIBM:
1373*0Sstevel@tonic-gate 			while ((c = ibc) != 0)
1374*0Sstevel@tonic-gate 			{
1375*0Sstevel@tonic-gate 				int nlflag = 0;
1376*0Sstevel@tonic-gate 
1377*0Sstevel@tonic-gate 			/* We may have to skip to the end of a long line */
1378*0Sstevel@tonic-gate 
1379*0Sstevel@tonic-gate 				if (skipf)
1380*0Sstevel@tonic-gate 				{
1381*0Sstevel@tonic-gate 					do {
1382*0Sstevel@tonic-gate 						if ((ic = *ip++) == '\n')
1383*0Sstevel@tonic-gate 						{
1384*0Sstevel@tonic-gate 							skipf = 0;
1385*0Sstevel@tonic-gate 							c--;
1386*0Sstevel@tonic-gate 							break;
1387*0Sstevel@tonic-gate 						}
1388*0Sstevel@tonic-gate 					} while (--c);
1389*0Sstevel@tonic-gate 					if ((ibc = c) == 0)
1390*0Sstevel@tonic-gate 					{
1391*0Sstevel@tonic-gate 						continue;
1392*0Sstevel@tonic-gate 							/* read another block */
1393*0Sstevel@tonic-gate 					}
1394*0Sstevel@tonic-gate 				}
1395*0Sstevel@tonic-gate 
1396*0Sstevel@tonic-gate 				/* If anything left, copy until newline */
1397*0Sstevel@tonic-gate 
1398*0Sstevel@tonic-gate 				if (c > (cbs - cbc + 1))
1399*0Sstevel@tonic-gate 				{
1400*0Sstevel@tonic-gate 					c = cbs - cbc + 1;
1401*0Sstevel@tonic-gate 				}
1402*0Sstevel@tonic-gate 				ibc -= c;
1403*0Sstevel@tonic-gate 				cbc += c;
1404*0Sstevel@tonic-gate 				obc += c;
1405*0Sstevel@tonic-gate 
1406*0Sstevel@tonic-gate 				switch (conv)
1407*0Sstevel@tonic-gate 				{
1408*0Sstevel@tonic-gate 				case BLOCK:
1409*0Sstevel@tonic-gate 					do {
1410*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1411*0Sstevel@tonic-gate 						{
1412*0Sstevel@tonic-gate 							*op++ = ic;
1413*0Sstevel@tonic-gate 						}
1414*0Sstevel@tonic-gate 						else
1415*0Sstevel@tonic-gate 						{
1416*0Sstevel@tonic-gate 							nlflag = 1;
1417*0Sstevel@tonic-gate 							break;
1418*0Sstevel@tonic-gate 						}
1419*0Sstevel@tonic-gate 					} while (--c);
1420*0Sstevel@tonic-gate 					break;
1421*0Sstevel@tonic-gate 
1422*0Sstevel@tonic-gate 				case LCBLOCK:
1423*0Sstevel@tonic-gate 					do {
1424*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1425*0Sstevel@tonic-gate 						{
1426*0Sstevel@tonic-gate 							*op++ = utol[ic];
1427*0Sstevel@tonic-gate 						}
1428*0Sstevel@tonic-gate 						else
1429*0Sstevel@tonic-gate 						{
1430*0Sstevel@tonic-gate 							nlflag = 1;
1431*0Sstevel@tonic-gate 							break;
1432*0Sstevel@tonic-gate 						}
1433*0Sstevel@tonic-gate 					} while (--c);
1434*0Sstevel@tonic-gate 					break;
1435*0Sstevel@tonic-gate 
1436*0Sstevel@tonic-gate 				case UCBLOCK:
1437*0Sstevel@tonic-gate 					do {
1438*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1439*0Sstevel@tonic-gate 						{
1440*0Sstevel@tonic-gate 							*op++ = ltou[ic];
1441*0Sstevel@tonic-gate 						}
1442*0Sstevel@tonic-gate 						else
1443*0Sstevel@tonic-gate 						{
1444*0Sstevel@tonic-gate 							nlflag = 1;
1445*0Sstevel@tonic-gate 							break;
1446*0Sstevel@tonic-gate 						}
1447*0Sstevel@tonic-gate 					} while (--c);
1448*0Sstevel@tonic-gate 					break;
1449*0Sstevel@tonic-gate 
1450*0Sstevel@tonic-gate 				case EBCDIC:
1451*0Sstevel@tonic-gate 					do {
1452*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1453*0Sstevel@tonic-gate 						{
1454*0Sstevel@tonic-gate 							*op++ = atoe[ic];
1455*0Sstevel@tonic-gate 						}
1456*0Sstevel@tonic-gate 						else
1457*0Sstevel@tonic-gate 						{
1458*0Sstevel@tonic-gate 							nlflag = 1;
1459*0Sstevel@tonic-gate 							break;
1460*0Sstevel@tonic-gate 						}
1461*0Sstevel@tonic-gate 					} while (--c);
1462*0Sstevel@tonic-gate 					break;
1463*0Sstevel@tonic-gate 
1464*0Sstevel@tonic-gate 				case LCEBCDIC:
1465*0Sstevel@tonic-gate 					do {
1466*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1467*0Sstevel@tonic-gate 						{
1468*0Sstevel@tonic-gate 							*op++ = atoe[utol[ic]];
1469*0Sstevel@tonic-gate 						}
1470*0Sstevel@tonic-gate 						else
1471*0Sstevel@tonic-gate 						{
1472*0Sstevel@tonic-gate 							nlflag = 1;
1473*0Sstevel@tonic-gate 							break;
1474*0Sstevel@tonic-gate 						}
1475*0Sstevel@tonic-gate 					} while (--c);
1476*0Sstevel@tonic-gate 					break;
1477*0Sstevel@tonic-gate 
1478*0Sstevel@tonic-gate 				case UCEBCDIC:
1479*0Sstevel@tonic-gate 					do {
1480*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1481*0Sstevel@tonic-gate 						{
1482*0Sstevel@tonic-gate 							*op++ = atoe[ltou[ic]];
1483*0Sstevel@tonic-gate 						}
1484*0Sstevel@tonic-gate 						else
1485*0Sstevel@tonic-gate 						{
1486*0Sstevel@tonic-gate 							nlflag = 1;
1487*0Sstevel@tonic-gate 							break;
1488*0Sstevel@tonic-gate 						}
1489*0Sstevel@tonic-gate 					} while (--c);
1490*0Sstevel@tonic-gate 					break;
1491*0Sstevel@tonic-gate 
1492*0Sstevel@tonic-gate 				case IBM:
1493*0Sstevel@tonic-gate 					do {
1494*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1495*0Sstevel@tonic-gate 						{
1496*0Sstevel@tonic-gate 							*op++ = atoibm[ic];
1497*0Sstevel@tonic-gate 						}
1498*0Sstevel@tonic-gate 						else
1499*0Sstevel@tonic-gate 						{
1500*0Sstevel@tonic-gate 							nlflag = 1;
1501*0Sstevel@tonic-gate 							break;
1502*0Sstevel@tonic-gate 						}
1503*0Sstevel@tonic-gate 					} while (--c);
1504*0Sstevel@tonic-gate 					break;
1505*0Sstevel@tonic-gate 
1506*0Sstevel@tonic-gate 				case LCIBM:
1507*0Sstevel@tonic-gate 					do {
1508*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1509*0Sstevel@tonic-gate 						{
1510*0Sstevel@tonic-gate 						*op++ = atoibm[utol[ic]];
1511*0Sstevel@tonic-gate 						}
1512*0Sstevel@tonic-gate 						else
1513*0Sstevel@tonic-gate 						{
1514*0Sstevel@tonic-gate 							nlflag = 1;
1515*0Sstevel@tonic-gate 							break;
1516*0Sstevel@tonic-gate 						}
1517*0Sstevel@tonic-gate 					} while (--c);
1518*0Sstevel@tonic-gate 					break;
1519*0Sstevel@tonic-gate 
1520*0Sstevel@tonic-gate 				case UCIBM:
1521*0Sstevel@tonic-gate 					do {
1522*0Sstevel@tonic-gate 						if ((ic = *ip++) != '\n')
1523*0Sstevel@tonic-gate 						{
1524*0Sstevel@tonic-gate 						*op++ = atoibm[ltou[ic]];
1525*0Sstevel@tonic-gate 						}
1526*0Sstevel@tonic-gate 						else
1527*0Sstevel@tonic-gate 						{
1528*0Sstevel@tonic-gate 							nlflag = 1;
1529*0Sstevel@tonic-gate 							break;
1530*0Sstevel@tonic-gate 						}
1531*0Sstevel@tonic-gate 					} while (--c);
1532*0Sstevel@tonic-gate 					break;
1533*0Sstevel@tonic-gate 				}
1534*0Sstevel@tonic-gate 
1535*0Sstevel@tonic-gate 			/* If newline found, update all the counters and */
1536*0Sstevel@tonic-gate 			/* pointers, pad with trailing blanks if necessary */
1537*0Sstevel@tonic-gate 
1538*0Sstevel@tonic-gate 				if (nlflag)
1539*0Sstevel@tonic-gate 				{
1540*0Sstevel@tonic-gate 					ibc += c - 1;
1541*0Sstevel@tonic-gate 					obc += cbs - cbc;
1542*0Sstevel@tonic-gate 					c += cbs - cbc;
1543*0Sstevel@tonic-gate 					cbc = 0;
1544*0Sstevel@tonic-gate 					if (c > 0)
1545*0Sstevel@tonic-gate 					{
1546*0Sstevel@tonic-gate 					/* Use the right kind of blank */
1547*0Sstevel@tonic-gate 
1548*0Sstevel@tonic-gate 						switch (conv)
1549*0Sstevel@tonic-gate 						{
1550*0Sstevel@tonic-gate 						case BLOCK:
1551*0Sstevel@tonic-gate 						case LCBLOCK:
1552*0Sstevel@tonic-gate 						case UCBLOCK:
1553*0Sstevel@tonic-gate 							ic = ' ';
1554*0Sstevel@tonic-gate 							break;
1555*0Sstevel@tonic-gate 
1556*0Sstevel@tonic-gate 						case EBCDIC:
1557*0Sstevel@tonic-gate 						case LCEBCDIC:
1558*0Sstevel@tonic-gate 						case UCEBCDIC:
1559*0Sstevel@tonic-gate 							ic = atoe[' '];
1560*0Sstevel@tonic-gate 							break;
1561*0Sstevel@tonic-gate 
1562*0Sstevel@tonic-gate 						case IBM:
1563*0Sstevel@tonic-gate 						case LCIBM:
1564*0Sstevel@tonic-gate 						case UCIBM:
1565*0Sstevel@tonic-gate 							ic = atoibm[' '];
1566*0Sstevel@tonic-gate 							break;
1567*0Sstevel@tonic-gate 						}
1568*0Sstevel@tonic-gate 
1569*0Sstevel@tonic-gate 						/* Pad with trailing blanks */
1570*0Sstevel@tonic-gate 
1571*0Sstevel@tonic-gate 						do {
1572*0Sstevel@tonic-gate 							*op++ = ic;
1573*0Sstevel@tonic-gate 						} while (--c);
1574*0Sstevel@tonic-gate 					}
1575*0Sstevel@tonic-gate 				}
1576*0Sstevel@tonic-gate 
1577*0Sstevel@tonic-gate 			/* If not end of line, this line may be too long */
1578*0Sstevel@tonic-gate 
1579*0Sstevel@tonic-gate 				else if (cbc > cbs)
1580*0Sstevel@tonic-gate 				{
1581*0Sstevel@tonic-gate 					skipf = 1; /* note skip in progress */
1582*0Sstevel@tonic-gate 					obc--;
1583*0Sstevel@tonic-gate 					op--;
1584*0Sstevel@tonic-gate 					cbc = 0;
1585*0Sstevel@tonic-gate 					ntrunc++;  /* count another long line */
1586*0Sstevel@tonic-gate 				}
1587*0Sstevel@tonic-gate 
1588*0Sstevel@tonic-gate 				/* Flush the output buffer if full */
1589*0Sstevel@tonic-gate 
1590*0Sstevel@tonic-gate 				while (obc >= obs)
1591*0Sstevel@tonic-gate 				{
1592*0Sstevel@tonic-gate 					op = flsh();
1593*0Sstevel@tonic-gate 				}
1594*0Sstevel@tonic-gate 			}
1595*0Sstevel@tonic-gate 			break;
1596*0Sstevel@tonic-gate 		}
1597*0Sstevel@tonic-gate 	}
1598*0Sstevel@tonic-gate }
1599*0Sstevel@tonic-gate 
1600*0Sstevel@tonic-gate /* match ************************************************************** */
1601*0Sstevel@tonic-gate /*									*/
1602*0Sstevel@tonic-gate /* Compare two text strings for equality				*/
1603*0Sstevel@tonic-gate /*									*/
1604*0Sstevel@tonic-gate /* Arg:		s - pointer to string to match with a command arg	*/
1605*0Sstevel@tonic-gate /* Global arg:	string - pointer to command arg				*/
1606*0Sstevel@tonic-gate /*									*/
1607*0Sstevel@tonic-gate /* Return:	1 if match, 0 if no match				*/
1608*0Sstevel@tonic-gate /*		If match, also reset `string' to point to the text	*/
1609*0Sstevel@tonic-gate /*		that follows the matching text.				*/
1610*0Sstevel@tonic-gate /*									*/
1611*0Sstevel@tonic-gate /* ********************************************************************	*/
1612*0Sstevel@tonic-gate 
1613*0Sstevel@tonic-gate static int
1614*0Sstevel@tonic-gate match(s)
1615*0Sstevel@tonic-gate char *s;
1616*0Sstevel@tonic-gate {
1617*0Sstevel@tonic-gate 	char *cs;
1618*0Sstevel@tonic-gate 
1619*0Sstevel@tonic-gate 	cs = string;
1620*0Sstevel@tonic-gate 	while (*cs++ == *s)
1621*0Sstevel@tonic-gate 	{
1622*0Sstevel@tonic-gate 		if (*s++ == '\0')
1623*0Sstevel@tonic-gate 		{
1624*0Sstevel@tonic-gate 			goto true;
1625*0Sstevel@tonic-gate 		}
1626*0Sstevel@tonic-gate 	}
1627*0Sstevel@tonic-gate 	if (*s != '\0')
1628*0Sstevel@tonic-gate 	{
1629*0Sstevel@tonic-gate 		return (0);
1630*0Sstevel@tonic-gate 	}
1631*0Sstevel@tonic-gate 
1632*0Sstevel@tonic-gate true:
1633*0Sstevel@tonic-gate 	cs--;
1634*0Sstevel@tonic-gate 	string = cs;
1635*0Sstevel@tonic-gate 	return (1);
1636*0Sstevel@tonic-gate }
1637*0Sstevel@tonic-gate 
1638*0Sstevel@tonic-gate /* number ************************************************************* */
1639*0Sstevel@tonic-gate /*									*/
1640*0Sstevel@tonic-gate /* Convert a numeric arg to binary					*/
1641*0Sstevel@tonic-gate /*									*/
1642*0Sstevel@tonic-gate /* Arg:		big - maximum valid input number			*/
1643*0Sstevel@tonic-gate /* Global arg:	string - pointer to command arg				*/
1644*0Sstevel@tonic-gate /*									*/
1645*0Sstevel@tonic-gate /* Valid forms:	123 | 123k | 123w | 123b | 123*123 | 123x123		*/
1646*0Sstevel@tonic-gate /*		plus combinations such as 2b*3kw*4w			*/
1647*0Sstevel@tonic-gate /*									*/
1648*0Sstevel@tonic-gate /* Return:	converted number					*/
1649*0Sstevel@tonic-gate /*									*/
1650*0Sstevel@tonic-gate /* ********************************************************************	*/
1651*0Sstevel@tonic-gate 
1652*0Sstevel@tonic-gate static unsigned long long
1653*0Sstevel@tonic-gate number(big)
1654*0Sstevel@tonic-gate long long big;
1655*0Sstevel@tonic-gate {
1656*0Sstevel@tonic-gate 	char *cs;
1657*0Sstevel@tonic-gate 	long long n;
1658*0Sstevel@tonic-gate 	long long cut = BIG / 10;	/* limit to avoid overflow */
1659*0Sstevel@tonic-gate 
1660*0Sstevel@tonic-gate 	cs = string;
1661*0Sstevel@tonic-gate 	n = 0;
1662*0Sstevel@tonic-gate 	while ((*cs >= '0') && (*cs <= '9') && (n <= cut))
1663*0Sstevel@tonic-gate 	{
1664*0Sstevel@tonic-gate 		n = n*10 + *cs++ - '0';
1665*0Sstevel@tonic-gate 	}
1666*0Sstevel@tonic-gate 	for (;;)
1667*0Sstevel@tonic-gate 	{
1668*0Sstevel@tonic-gate 		switch (*cs++)
1669*0Sstevel@tonic-gate 		{
1670*0Sstevel@tonic-gate 
1671*0Sstevel@tonic-gate 		case 'k':
1672*0Sstevel@tonic-gate 			n *= 1024;
1673*0Sstevel@tonic-gate 			continue;
1674*0Sstevel@tonic-gate 
1675*0Sstevel@tonic-gate 		case 'w':
1676*0Sstevel@tonic-gate 			n *= 2;
1677*0Sstevel@tonic-gate 			continue;
1678*0Sstevel@tonic-gate 
1679*0Sstevel@tonic-gate 		case 'b':
1680*0Sstevel@tonic-gate 			n *= BSIZE;
1681*0Sstevel@tonic-gate 			continue;
1682*0Sstevel@tonic-gate 
1683*0Sstevel@tonic-gate 		case '*':
1684*0Sstevel@tonic-gate 		case 'x':
1685*0Sstevel@tonic-gate 			string = cs;
1686*0Sstevel@tonic-gate 			n *= number(BIG);
1687*0Sstevel@tonic-gate 
1688*0Sstevel@tonic-gate 		/* FALLTHROUGH */
1689*0Sstevel@tonic-gate 		/* Fall into exit test, recursion has read rest of string */
1690*0Sstevel@tonic-gate 		/* End of string, check for a valid number */
1691*0Sstevel@tonic-gate 
1692*0Sstevel@tonic-gate 		case '\0':
1693*0Sstevel@tonic-gate 			if ((n > big) || (n < 0))
1694*0Sstevel@tonic-gate 			{
1695*0Sstevel@tonic-gate 				(void) fprintf(stderr, "dd: %s \"%llu\"\n",
1696*0Sstevel@tonic-gate 					gettext("argument out of range:"), n);
1697*0Sstevel@tonic-gate 				exit(2);
1698*0Sstevel@tonic-gate 			}
1699*0Sstevel@tonic-gate 			return (n);
1700*0Sstevel@tonic-gate 
1701*0Sstevel@tonic-gate 		default:
1702*0Sstevel@tonic-gate 			(void) fprintf(stderr, "dd: %s \"%s\"\n",
1703*0Sstevel@tonic-gate 				gettext("bad numeric argument:"), string);
1704*0Sstevel@tonic-gate 			exit(2);
1705*0Sstevel@tonic-gate 		}
1706*0Sstevel@tonic-gate 	} /* never gets here */
1707*0Sstevel@tonic-gate }
1708*0Sstevel@tonic-gate 
1709*0Sstevel@tonic-gate /* flsh *************************************************************** */
1710*0Sstevel@tonic-gate /*									*/
1711*0Sstevel@tonic-gate /* Flush the output buffer, move any excess bytes down to the beginning	*/
1712*0Sstevel@tonic-gate /*									*/
1713*0Sstevel@tonic-gate /* Arg:		none							*/
1714*0Sstevel@tonic-gate /* Global args:	obuf, obc, obs, nofr, nopr				*/
1715*0Sstevel@tonic-gate /*									*/
1716*0Sstevel@tonic-gate /* Return:	Pointer to the first free byte in the output buffer.	*/
1717*0Sstevel@tonic-gate /*		Also reset `obc' to account for moved bytes.		*/
1718*0Sstevel@tonic-gate /*									*/
1719*0Sstevel@tonic-gate /* ********************************************************************	*/
1720*0Sstevel@tonic-gate 
1721*0Sstevel@tonic-gate static unsigned char
1722*0Sstevel@tonic-gate *flsh()
1723*0Sstevel@tonic-gate {
1724*0Sstevel@tonic-gate 	unsigned char *op, *cp;
1725*0Sstevel@tonic-gate 	int bc;
1726*0Sstevel@tonic-gate 	unsigned int oc;
1727*0Sstevel@tonic-gate 
1728*0Sstevel@tonic-gate 	if (obc)			/* don't flush if the buffer is empty */
1729*0Sstevel@tonic-gate 	{
1730*0Sstevel@tonic-gate 		if (obc >= obs) {
1731*0Sstevel@tonic-gate 			oc = obs;
1732*0Sstevel@tonic-gate 			nofr++;		/* count a full output buffer */
1733*0Sstevel@tonic-gate 		}
1734*0Sstevel@tonic-gate 		else
1735*0Sstevel@tonic-gate 		{
1736*0Sstevel@tonic-gate 			oc = obc;
1737*0Sstevel@tonic-gate 			nopr++;		/* count a partial output buffer */
1738*0Sstevel@tonic-gate 		}
1739*0Sstevel@tonic-gate 		bc = write(obf, (char *)obuf, oc);
1740*0Sstevel@tonic-gate 		if (bc != oc) {
1741*0Sstevel@tonic-gate 			if (bc < 0)
1742*0Sstevel@tonic-gate 				perror("write");
1743*0Sstevel@tonic-gate 			else
1744*0Sstevel@tonic-gate 			(void) fprintf(stderr,
1745*0Sstevel@tonic-gate 				gettext("dd: unexpected short write, "
1746*0Sstevel@tonic-gate 				"wrote %d bytes, expected %d\n"), bc, oc);
1747*0Sstevel@tonic-gate 			term(2);
1748*0Sstevel@tonic-gate 		}
1749*0Sstevel@tonic-gate 		obc -= oc;
1750*0Sstevel@tonic-gate 		op = obuf;
1751*0Sstevel@tonic-gate 
1752*0Sstevel@tonic-gate 		/* If any data in the conversion buffer, move it into */
1753*0Sstevel@tonic-gate 		/* the output buffer */
1754*0Sstevel@tonic-gate 
1755*0Sstevel@tonic-gate 		if (obc) {
1756*0Sstevel@tonic-gate 			cp = obuf + obs;
1757*0Sstevel@tonic-gate 			bc = obc;
1758*0Sstevel@tonic-gate 			do {
1759*0Sstevel@tonic-gate 				*op++ = *cp++;
1760*0Sstevel@tonic-gate 			} while (--bc);
1761*0Sstevel@tonic-gate 		}
1762*0Sstevel@tonic-gate 		return (op);
1763*0Sstevel@tonic-gate 	}
1764*0Sstevel@tonic-gate 	return (obuf);
1765*0Sstevel@tonic-gate }
1766*0Sstevel@tonic-gate 
1767*0Sstevel@tonic-gate /* term *************************************************************** */
1768*0Sstevel@tonic-gate /*									*/
1769*0Sstevel@tonic-gate /* Write record statistics, then exit					*/
1770*0Sstevel@tonic-gate /*									*/
1771*0Sstevel@tonic-gate /* Arg:		c - exit status code					*/
1772*0Sstevel@tonic-gate /*									*/
1773*0Sstevel@tonic-gate /* Return:	no return, calls exit					*/
1774*0Sstevel@tonic-gate /*									*/
1775*0Sstevel@tonic-gate /* ********************************************************************	*/
1776*0Sstevel@tonic-gate 
1777*0Sstevel@tonic-gate static void
1778*0Sstevel@tonic-gate term(c)
1779*0Sstevel@tonic-gate int c;
1780*0Sstevel@tonic-gate {
1781*0Sstevel@tonic-gate 	stats();
1782*0Sstevel@tonic-gate 	exit(c);
1783*0Sstevel@tonic-gate }
1784*0Sstevel@tonic-gate 
1785*0Sstevel@tonic-gate /* stats ************************************************************** */
1786*0Sstevel@tonic-gate /*									*/
1787*0Sstevel@tonic-gate /* Write record statistics onto standard error				*/
1788*0Sstevel@tonic-gate /*									*/
1789*0Sstevel@tonic-gate /* Args:	none							*/
1790*0Sstevel@tonic-gate /* Global args:	nifr, nipr, nofr, nopr, ntrunc				*/
1791*0Sstevel@tonic-gate /*									*/
1792*0Sstevel@tonic-gate /* Return:	void							*/
1793*0Sstevel@tonic-gate /*									*/
1794*0Sstevel@tonic-gate /* ********************************************************************	*/
1795*0Sstevel@tonic-gate 
1796*0Sstevel@tonic-gate static void
1797*0Sstevel@tonic-gate stats()
1798*0Sstevel@tonic-gate {
1799*0Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("%llu+%llu records in\n"), nifr, nipr);
1800*0Sstevel@tonic-gate 	(void) fprintf(stderr, gettext("%llu+%llu records out\n"), nofr, nopr);
1801*0Sstevel@tonic-gate 	if (ntrunc) {
1802*0Sstevel@tonic-gate 		(void) fprintf(stderr,
1803*0Sstevel@tonic-gate 			gettext("%llu truncated record(s)\n"), ntrunc);
1804*0Sstevel@tonic-gate 	}
1805*0Sstevel@tonic-gate }
1806