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