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