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