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