Home | History | Annotate | Download | only in dd
      1 /*
      2  * CDDL HEADER START
      3  *
      4  * The contents of this file are subject to the terms of the
      5  * Common Development and Distribution License, Version 1.0 only
      6  * (the "License").  You may not use this file except in compliance
      7  * with the License.
      8  *
      9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
     10  * or http://www.opensolaris.org/os/licensing.
     11  * See the License for the specific language governing permissions
     12  * and limitations under the License.
     13  *
     14  * When distributing Covered Code, include this CDDL HEADER in each
     15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
     16  * If applicable, add the following below this CDDL HEADER, with the
     17  * fields enclosed by brackets "[]" replaced with your own identifying
     18  * information: Portions Copyright [yyyy] [name of copyright owner]
     19  *
     20  * CDDL HEADER END
     21  */
     22 
     23 /*
     24  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
     25  * Use is subject to license terms.
     26  */
     27 
     28 /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
     29 /*	  All Rights Reserved  	*/
     30 
     31 #pragma ident	"%Z%%M%	%I%	%E% SMI"
     32 
     33 /*
     34  *	convert and copy
     35  */
     36 
     37 #include	<stdio.h>
     38 #include	<signal.h>
     39 #include	<fcntl.h>
     40 #include	<sys/param.h>
     41 #include	<sys/types.h>
     42 #include	<sys/sysmacros.h>
     43 #include	<sys/stat.h>
     44 #include	<unistd.h>
     45 #include	<stdlib.h>
     46 #include	<locale.h>
     47 #include	<string.h>
     48 
     49 /* The BIG parameter is machine dependent.  It should be a long integer	*/
     50 /* constant that can be used by the number parser to check the validity	*/
     51 /* of numeric parameters.  On 16-bit machines, it should probably be	*/
     52 /* the maximum unsigned integer, 0177777L.  On 32-bit machines where	*/
     53 /* longs are the same size as ints, the maximum signed integer is more	*/
     54 /* appropriate.  This value is 017777777777L. In 64 bit environments,   */
     55 /* the maximum signed integer value is 0777777777777777777777LL		*/
     56 
     57 #define	BIG	0777777777777777777777LL
     58 
     59 #define	BSIZE	512
     60 
     61 /* Option parameters */
     62 
     63 #define	COPY		0	/* file copy, preserve input block size */
     64 #define	REBLOCK		1	/* file copy, change block size */
     65 #define	LCREBLOCK	2	/* file copy, convert to lower case */
     66 #define	UCREBLOCK	3	/* file copy, convert to upper case */
     67 #define	NBASCII		4	/* file copy, convert from EBCDIC to ASCII */
     68 #define	LCNBASCII	5	/* file copy, EBCDIC to lower case ASCII */
     69 #define	UCNBASCII	6	/* file copy, EBCDIC to upper case ASCII */
     70 #define	NBEBCDIC	7	/* file copy, convert from ASCII to EBCDIC */
     71 #define	LCNBEBCDIC	8	/* file copy, ASCII to lower case EBCDIC */
     72 #define	UCNBEBCDIC	9	/* file copy, ASCII to upper case EBCDIC */
     73 #define	NBIBM		10	/* file copy, convert from ASCII to IBM */
     74 #define	LCNBIBM		11	/* file copy, ASCII to lower case IBM */
     75 #define	UCNBIBM		12	/* file copy, ASCII to upper case IBM */
     76 #define	UNBLOCK		13	/* convert blocked ASCII to ASCII */
     77 #define	LCUNBLOCK	14	/* convert blocked ASCII to lower case ASCII */
     78 #define	UCUNBLOCK	15	/* convert blocked ASCII to upper case ASCII */
     79 #define	ASCII		16	/* convert blocked EBCDIC to ASCII */
     80 #define	LCASCII		17	/* convert blocked EBCDIC to lower case ASCII */
     81 #define	UCASCII		18	/* convert blocked EBCDIC to upper case ASCII */
     82 #define	BLOCK		19	/* convert ASCII to blocked ASCII */
     83 #define	LCBLOCK		20	/* convert ASCII to lower case blocked ASCII */
     84 #define	UCBLOCK		21	/* convert ASCII to upper case blocked ASCII */
     85 #define	EBCDIC		22	/* convert ASCII to blocked EBCDIC */
     86 #define	LCEBCDIC	23	/* convert ASCII to lower case blocked EBCDIC */
     87 #define	UCEBCDIC	24	/* convert ASCII to upper case blocked EBCDIC */
     88 #define	IBM		25	/* convert ASCII to blocked IBM */
     89 #define	LCIBM		26	/* convert ASCII to lower case blocked IBM */
     90 #define	UCIBM		27	/* convert ASCII to upper case blocked IBM */
     91 #define	LCASE		01	/* flag - convert to lower case */
     92 #define	UCASE		02	/* flag - convert to upper case */
     93 #define	SWAB		04	/* flag - swap bytes before conversion */
     94 #define	NERR		010	/* flag - proceed on input errors */
     95 #define	SYNC		020	/* flag - pad short input blocks with nulls */
     96 #define	BADLIMIT	5	/* give up if no progress after BADLIMIT trys */
     97 #define	SVR4XLATE	0	/* use default EBCDIC translation */
     98 #define	BSDXLATE	1	/* use BSD-compatible EBCDIC translation */
     99 
    100 #define	USAGE\
    101 	"usage: dd [if=file] [of=file] [ibs=n|nk|nb|nxm] [obs=n|nk|nb|nxm]\n"\
    102 	"	   [bs=n|nk|nb|nxm] [cbs=n|nk|nb|nxm] [files=n] [skip=n]\n"\
    103 	"	   [iseek=n] [oseek=n] [seek=n] [count=n] [conv=[ascii]\n"\
    104 	"	   [,ebcdic][,ibm][,asciib][,ebcdicb][,ibmb]\n"\
    105 	"	   [,block|unblock][,lcase|ucase][,swab]\n"\
    106 	"	   [,noerror][,notrunc][,sync]]\n"
    107 
    108 /* Global references */
    109 
    110 /* Local routine declarations */
    111 
    112 static int	match(char *);
    113 static void		term();
    114 static unsigned long long	number();
    115 static unsigned char	*flsh();
    116 static void		stats();
    117 
    118 /* Local data definitions */
    119 
    120 static unsigned ibs;	/* input buffer size */
    121 static unsigned obs;	/* output buffer size */
    122 static unsigned bs;	/* buffer size, overrules ibs and obs */
    123 static unsigned cbs;	/* conversion buffer size, used for block conversions */
    124 static unsigned ibc;	/* number of bytes still in the input buffer */
    125 static unsigned obc;	/* number of bytes in the output buffer */
    126 static unsigned cbc;	/* number of bytes in the conversion buffer */
    127 
    128 static int	ibf;	/* input file descriptor */
    129 static int	obf;	/* output file descriptor */
    130 static int	cflag;	/* conversion option flags */
    131 static int	skipf;	/* if skipf == 1, skip rest of input line */
    132 static unsigned long long	nifr;	/* count of full input records */
    133 static unsigned long long	nipr;	/* count of partial input records */
    134 static unsigned long long	nofr;	/* count of full output records */
    135 static unsigned long long	nopr;	/* count of partial output records */
    136 static unsigned long long	ntrunc;	/* count of truncated input lines */
    137 static unsigned long long	nbad;	/* count of bad records since last */
    138 					/* good one */
    139 static int	files;	/* number of input files to concatenate (tape only) */
    140 static off_t	skip;	/* number of input records to skip */
    141 static off_t	iseekn;	/* number of input records to seek past */
    142 static off_t	oseekn;	/* number of output records to seek past */
    143 static unsigned long long	count;	/* number of input records to copy */
    144 			/* (0 = all) */
    145 static int	trantype; /* BSD or SVr4 compatible EBCDIC */
    146 
    147 static char		*string;	/* command arg pointer */
    148 static char		*ifile;		/* input file name pointer */
    149 static char		*ofile;		/* output file name pointer */
    150 static unsigned char	*ibuf;		/* input buffer pointer */
    151 static unsigned char	*obuf;		/* output buffer pointer */
    152 
    153 /* This is an EBCDIC to ASCII conversion table	*/
    154 /* from a proposed BTL standard April 16, 1979	*/
    155 
    156 static unsigned char svr4_etoa [] =
    157 {
    158 	0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
    159 	0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
    160 	0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
    161 	0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
    162 	0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
    163 	0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
    164 	0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
    165 	0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
    166 	0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
    167 	0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
    168 	0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
    169 	0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
    170 	0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
    171 	0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
    172 	0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
    173 	0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
    174 	0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
    175 	0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
    176 	0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
    177 	0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
    178 	0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
    179 	0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
    180 	0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
    181 	0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
    182 	0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
    183 	0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
    184 	0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
    185 	0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
    186 	0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
    187 	0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
    188 	0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
    189 	0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
    190 };
    191 
    192 /* This is an ASCII to EBCDIC conversion table	*/
    193 /* from a proposed BTL standard April 16, 1979	*/
    194 
    195 static unsigned char svr4_atoe [] =
    196 {
    197 	0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
    198 	0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
    199 	0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
    200 	0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
    201 	0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
    202 	0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
    203 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
    204 	0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
    205 	0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
    206 	0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
    207 	0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
    208 	0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155,
    209 	0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
    210 	0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
    211 	0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
    212 	0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007,
    213 	0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
    214 	0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
    215 	0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
    216 	0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
    217 	0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
    218 	0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
    219 	0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
    220 	0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
    221 	0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
    222 	0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236,
    223 	0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257,
    224 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
    225 	0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277,
    226 	0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
    227 	0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
    228 	0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
    229 };
    230 
    231 /* Table for ASCII to IBM (alternate EBCDIC) code conversion	*/
    232 
    233 static unsigned char svr4_atoibm[] =
    234 {
    235 	0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
    236 	0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
    237 	0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
    238 	0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
    239 	0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
    240 	0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
    241 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
    242 	0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
    243 	0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
    244 	0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
    245 	0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
    246 	0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
    247 	0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
    248 	0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
    249 	0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
    250 	0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
    251 	0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
    252 	0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
    253 	0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
    254 	0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
    255 	0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
    256 	0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
    257 	0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
    258 	0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
    259 	0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
    260 	0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
    261 	0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
    262 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
    263 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
    264 	0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
    265 	0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
    266 	0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
    267 };
    268 
    269 /* Table for conversion of ASCII to lower case ASCII	*/
    270 
    271 static unsigned char utol[] =
    272 {
    273 	0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
    274 	0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
    275 	0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
    276 	0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
    277 	0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
    278 	0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
    279 	0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
    280 	0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
    281 	0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
    282 	0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
    283 	0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
    284 	0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
    285 	0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
    286 	0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
    287 	0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
    288 	0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
    289 	0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
    290 	0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
    291 	0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
    292 	0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
    293 	0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
    294 	0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
    295 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
    296 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
    297 	0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
    298 	0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
    299 	0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
    300 	0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
    301 	0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
    302 	0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
    303 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
    304 	0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
    305 };
    306 
    307 /* Table for conversion of ASCII to upper case ASCII	*/
    308 
    309 static unsigned char ltou[] =
    310 {
    311 	0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
    312 	0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
    313 	0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
    314 	0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
    315 	0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
    316 	0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
    317 	0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
    318 	0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
    319 	0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
    320 	0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
    321 	0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
    322 	0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
    323 	0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
    324 	0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
    325 	0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
    326 	0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
    327 	0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
    328 	0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
    329 	0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
    330 	0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
    331 	0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
    332 	0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
    333 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
    334 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
    335 	0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
    336 	0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
    337 	0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
    338 	0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
    339 	0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
    340 	0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
    341 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
    342 	0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
    343 };
    344 
    345 /* BSD-compatible EBCDIC to ASCII translate table */
    346 
    347 static unsigned char	bsd_etoa[] =
    348 {
    349 	0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
    350 	0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
    351 	0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
    352 	0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
    353 	0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
    354 	0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
    355 	0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
    356 	0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
    357 	0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
    358 	0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041,
    359 	0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
    360 	0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136,
    361 	0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
    362 	0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077,
    363 	0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
    364 	0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
    365 	0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
    366 	0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
    367 	0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
    368 	0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
    369 	0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
    370 	0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
    371 	0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
    372 	0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
    373 	0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
    374 	0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
    375 	0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
    376 	0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
    377 	0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
    378 	0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
    379 	0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
    380 	0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
    381 };
    382 
    383 /* BSD-compatible ASCII to EBCDIC translate table */
    384 
    385 static unsigned char	bsd_atoe[] =
    386 {
    387 	0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
    388 	0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
    389 	0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
    390 	0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
    391 	0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
    392 	0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
    393 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
    394 	0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
    395 	0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
    396 	0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
    397 	0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
    398 	0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
    399 	0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
    400 	0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
    401 	0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
    402 	0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007,
    403 	0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
    404 	0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
    405 	0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
    406 	0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
    407 	0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
    408 	0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
    409 	0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
    410 	0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
    411 	0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
    412 	0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
    413 	0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
    414 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
    415 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
    416 	0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
    417 	0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
    418 	0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
    419 };
    420 
    421 /* BSD-compatible ASCII to IBM translate table */
    422 
    423 static unsigned char	bsd_atoibm[] =
    424 {
    425 	0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
    426 	0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
    427 	0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
    428 	0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
    429 	0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
    430 	0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
    431 	0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
    432 	0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
    433 	0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
    434 	0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
    435 	0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
    436 	0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
    437 	0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
    438 	0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
    439 	0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
    440 	0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
    441 	0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
    442 	0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
    443 	0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
    444 	0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
    445 	0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
    446 	0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
    447 	0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
    448 	0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
    449 	0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
    450 	0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
    451 	0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
    452 	0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
    453 	0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
    454 	0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
    455 	0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
    456 	0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
    457 };
    458 
    459 /* set up to use SVr4 ascii-ebcdic translation by default */
    460 
    461 static unsigned char *atoe = svr4_atoe;
    462 static unsigned char *etoa = svr4_etoa;
    463 static unsigned char *atoibm = svr4_atoibm;
    464 
    465 
    466 int
    467 main(int argc, char **argv)
    468 {
    469 	unsigned char *ip, *op; /* input and output buffer pointers */
    470 	int c;		/* character counter */
    471 	int ic;		/* input character */
    472 	int conv;		/* conversion option code */
    473 	int trunc;		/* whether output file is truncated */
    474 	struct stat file_stat;
    475 
    476 	/* Set option defaults */
    477 
    478 	ibs = BSIZE;
    479 	obs = BSIZE;
    480 	files = 1;
    481 	conv = COPY;
    482 	trunc = 1;			/* default: truncate output file */
    483 	trantype = SVR4XLATE;  /* use SVR4 EBCDIC by default */
    484 
    485 	/* Parse command options */
    486 
    487 	(void) setlocale(LC_ALL, "");
    488 #if !defined(TEXT_DOMAIN)	/* Should be defined by cc -D */
    489 #define	TEXT_DOMAIN "SYS_TEST"	/* Use this only if it weren't */
    490 #endif
    491 	(void) textdomain(TEXT_DOMAIN);
    492 
    493 	while ((c = getopt(argc, argv, "")) != EOF)
    494 		switch (c) {
    495 			case '?':
    496 			(void) fprintf(stderr, USAGE);
    497 			exit(2);
    498 		}
    499 
    500 	/* not getopt()'ed because dd has no options but only operand(s) */
    501 
    502 	for (c = optind; c < argc; c++)
    503 	{
    504 		string = argv[c];
    505 		if (match("ibs="))
    506 		{
    507 			ibs = (unsigned)number(BIG);
    508 			continue;
    509 		}
    510 		if (match("obs="))
    511 		{
    512 			obs = (unsigned)number(BIG);
    513 			continue;
    514 		}
    515 		if (match("cbs="))
    516 		{
    517 			cbs = (unsigned)number(BIG);
    518 			continue;
    519 		}
    520 		if (match("bs="))
    521 		{
    522 			bs = (unsigned)number(BIG);
    523 			continue;
    524 		}
    525 		if (match("if="))
    526 		{
    527 			ifile = string;
    528 			continue;
    529 		}
    530 		if (match("of="))
    531 		{
    532 			ofile = string;
    533 			continue;
    534 		}
    535 		if (match("skip="))
    536 		{
    537 			skip = number(BIG);
    538 			continue;
    539 		}
    540 		if (match("iseek="))
    541 		{
    542 			iseekn = number(BIG);
    543 			continue;
    544 		}
    545 		if (match("oseek="))
    546 		{
    547 			oseekn = number(BIG);
    548 			continue;
    549 		}
    550 		if (match("seek="))		/* retained for compatibility */
    551 		{
    552 			oseekn = number(BIG);
    553 			continue;
    554 		}
    555 		if (match("count="))
    556 		{
    557 			count = number(BIG);
    558 			continue;
    559 		}
    560 		if (match("files="))
    561 		{
    562 			files = (int)number(BIG);
    563 			continue;
    564 		}
    565 		if (match("conv="))
    566 		{
    567 			for (;;)
    568 			{
    569 				if (match(","))
    570 				{
    571 					continue;
    572 				}
    573 				if (*string == '\0')
    574 				{
    575 					break;
    576 				}
    577 				if (match("block"))
    578 				{
    579 					conv = BLOCK;
    580 					continue;
    581 				}
    582 				if (match("unblock"))
    583 				{
    584 					conv = UNBLOCK;
    585 					continue;
    586 				}
    587 
    588 				/* ebcdicb, ibmb, and asciib must precede */
    589 				/* ebcdic, ibm, and ascii in this test */
    590 
    591 				if (match("ebcdicb"))
    592 				{
    593 					conv = EBCDIC;
    594 					trantype = BSDXLATE;
    595 					continue;
    596 				}
    597 				if (match("ibmb"))
    598 				{
    599 					conv = IBM;
    600 					trantype = BSDXLATE;
    601 					continue;
    602 				}
    603 				if (match("asciib"))
    604 				{
    605 					conv = ASCII;
    606 					trantype = BSDXLATE;
    607 					continue;
    608 				}
    609 				if (match("ebcdic"))
    610 				{
    611 					conv = EBCDIC;
    612 					trantype = SVR4XLATE;
    613 					continue;
    614 				}
    615 				if (match("ibm"))
    616 				{
    617 					conv = IBM;
    618 					trantype = SVR4XLATE;
    619 					continue;
    620 				}
    621 				if (match("ascii"))
    622 				{
    623 					conv = ASCII;
    624 					trantype = SVR4XLATE;
    625 					continue;
    626 				}
    627 				if (match("lcase"))
    628 				{
    629 					cflag |= LCASE;
    630 					continue;
    631 				}
    632 				if (match("ucase"))
    633 				{
    634 					cflag |= UCASE;
    635 					continue;
    636 				}
    637 				if (match("swab"))
    638 				{
    639 					cflag |= SWAB;
    640 					continue;
    641 				}
    642 				if (match("noerror"))
    643 				{
    644 					cflag |= NERR;
    645 					continue;
    646 				}
    647 				if (match("notrunc"))
    648 				{
    649 					trunc = 0;
    650 					continue;
    651 				}
    652 				if (match("sync"))
    653 				{
    654 					cflag |= SYNC;
    655 					continue;
    656 				}
    657 				goto badarg;
    658 			}
    659 			continue;
    660 		}
    661 		badarg:
    662 		(void) fprintf(stderr, "dd: %s \"%s\"\n",
    663 			gettext("bad argument:"), string);
    664 		exit(2);
    665 	}
    666 
    667 	/* Perform consistency checks on options, decode strange conventions */
    668 
    669 	if (bs)
    670 	{
    671 		ibs = obs = bs;
    672 	}
    673 	if ((ibs == 0) || (obs == 0))
    674 	{
    675 		(void) fprintf(stderr, "dd: %s\n",
    676 			gettext("buffer sizes cannot be zero"));
    677 		exit(2);
    678 	}
    679 	if (conv == COPY)
    680 	{
    681 		if ((bs == 0) || (cflag&(LCASE|UCASE)))
    682 		{
    683 			conv = REBLOCK;
    684 		}
    685 	}
    686 	if (cbs == 0)
    687 	{
    688 		switch (conv)
    689 		{
    690 		case BLOCK:
    691 		case UNBLOCK:
    692 			conv = REBLOCK;
    693 			break;
    694 
    695 		case ASCII:
    696 			conv = NBASCII;
    697 			break;
    698 
    699 		case EBCDIC:
    700 			conv = NBEBCDIC;
    701 			break;
    702 
    703 		case IBM:
    704 			conv = NBIBM;
    705 			break;
    706 		}
    707 	}
    708 
    709 	/* Expand options into lower and upper case versions if necessary */
    710 
    711 	switch (conv)
    712 	{
    713 	case REBLOCK:
    714 		if (cflag&LCASE)
    715 			conv = LCREBLOCK;
    716 		else if (cflag&UCASE)
    717 			conv = UCREBLOCK;
    718 		break;
    719 
    720 	case UNBLOCK:
    721 		if (cflag&LCASE)
    722 			conv = LCUNBLOCK;
    723 		else if (cflag&UCASE)
    724 			conv = UCUNBLOCK;
    725 		break;
    726 
    727 	case BLOCK:
    728 		if (cflag&LCASE)
    729 			conv = LCBLOCK;
    730 		else if (cflag&UCASE)
    731 			conv = UCBLOCK;
    732 		break;
    733 
    734 	case ASCII:
    735 		if (cflag&LCASE)
    736 			conv = LCASCII;
    737 		else if (cflag&UCASE)
    738 			conv = UCASCII;
    739 		break;
    740 
    741 	case NBASCII:
    742 		if (cflag&LCASE)
    743 			conv = LCNBASCII;
    744 		else if (cflag&UCASE)
    745 			conv = UCNBASCII;
    746 		break;
    747 
    748 	case EBCDIC:
    749 		if (cflag&LCASE)
    750 			conv = LCEBCDIC;
    751 		else if (cflag&UCASE)
    752 			conv = UCEBCDIC;
    753 		break;
    754 
    755 	case NBEBCDIC:
    756 		if (cflag&LCASE)
    757 			conv = LCNBEBCDIC;
    758 		else if (cflag&UCASE)
    759 			conv = UCNBEBCDIC;
    760 		break;
    761 
    762 	case IBM:
    763 		if (cflag&LCASE)
    764 			conv = LCIBM;
    765 		else if (cflag&UCASE)
    766 			conv = UCIBM;
    767 		break;
    768 
    769 	case NBIBM:
    770 		if (cflag&LCASE)
    771 			conv = LCNBIBM;
    772 		else if (cflag&UCASE)
    773 			conv = UCNBIBM;
    774 		break;
    775 	}
    776 
    777 	/* If BSD-compatible translation is selected, change the tables */
    778 
    779 	if (trantype == BSDXLATE) {
    780 		atoe = bsd_atoe;
    781 		atoibm = bsd_atoibm;
    782 		etoa = bsd_etoa;
    783 	}
    784 	/* Open the input file, or duplicate standard input */
    785 
    786 	ibf = -1;
    787 	if (ifile)
    788 	{
    789 		ibf = open(ifile, 0);
    790 	}
    791 #ifndef STANDALONE
    792 	else
    793 	{
    794 		ifile = "";
    795 		ibf = dup(0);
    796 	}
    797 #endif
    798 	if (ibf == -1)
    799 	{
    800 		(void) fprintf(stderr, "dd: %s: ", ifile);
    801 		perror("open");
    802 		exit(2);
    803 	}
    804 
    805 	/* Open the output file, or duplicate standard output */
    806 
    807 	obf = -1;
    808 	if (ofile)
    809 	{
    810 		if (trunc == 0)	/* do not truncate output file */
    811 			obf = open(ofile, (O_WRONLY|O_CREAT),
    812 			(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
    813 		else if (oseekn && (trunc == 1))
    814 		{
    815 			obf = open(ofile, O_WRONLY|O_CREAT,
    816 			(S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
    817 			if (obf == -1)
    818 			{
    819 				(void) fprintf(stderr, "dd: %s: ", ofile);
    820 				perror("open");
    821 				exit(2);
    822 			}
    823 			(void)