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