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