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