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