Merge commit '00f1a4f432b3d8aad1aa270e91c44c57f03ef407'
[unleashed.git] / usr / src / cmd / dd / dd.c
blob853aca43b860e28ecf299ada3eff22a637f037b8
1 /*
2 * CDDL HEADER START
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.
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.
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]
20 * CDDL HEADER END
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.
31 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
32 /* All Rights Reserved */
35 * convert and copy
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>
53 /* The BIG parameter is machine dependent. It should be a long integer */
54 /* constant that can be used by the number parser to check the validity */
55 /* of numeric parameters. On 16-bit machines, it should probably be */
56 /* the maximum unsigned integer, 0177777L. On 32-bit machines where */
57 /* longs are the same size as ints, the maximum signed integer is more */
58 /* appropriate. This value is 017777777777L. In 64 bit environments, */
59 /* the maximum signed integer value is 0777777777777777777777LL */
61 #define BIG 0777777777777777777777LL
63 #define BSIZE 512
65 /* Option parameters */
67 #define COPY 0 /* file copy, preserve input block size */
68 #define REBLOCK 1 /* file copy, change block size */
69 #define LCREBLOCK 2 /* file copy, convert to lower case */
70 #define UCREBLOCK 3 /* file copy, convert to upper case */
71 #define NBASCII 4 /* file copy, convert from EBCDIC to ASCII */
72 #define LCNBASCII 5 /* file copy, EBCDIC to lower case ASCII */
73 #define UCNBASCII 6 /* file copy, EBCDIC to upper case ASCII */
74 #define NBEBCDIC 7 /* file copy, convert from ASCII to EBCDIC */
75 #define LCNBEBCDIC 8 /* file copy, ASCII to lower case EBCDIC */
76 #define UCNBEBCDIC 9 /* file copy, ASCII to upper case EBCDIC */
77 #define NBIBM 10 /* file copy, convert from ASCII to IBM */
78 #define LCNBIBM 11 /* file copy, ASCII to lower case IBM */
79 #define UCNBIBM 12 /* file copy, ASCII to upper case IBM */
80 #define UNBLOCK 13 /* convert blocked ASCII to ASCII */
81 #define LCUNBLOCK 14 /* convert blocked ASCII to lower case ASCII */
82 #define UCUNBLOCK 15 /* convert blocked ASCII to upper case ASCII */
83 #define ASCII 16 /* convert blocked EBCDIC to ASCII */
84 #define LCASCII 17 /* convert blocked EBCDIC to lower case ASCII */
85 #define UCASCII 18 /* convert blocked EBCDIC to upper case ASCII */
86 #define BLOCK 19 /* convert ASCII to blocked ASCII */
87 #define LCBLOCK 20 /* convert ASCII to lower case blocked ASCII */
88 #define UCBLOCK 21 /* convert ASCII to upper case blocked ASCII */
89 #define EBCDIC 22 /* convert ASCII to blocked EBCDIC */
90 #define LCEBCDIC 23 /* convert ASCII to lower case blocked EBCDIC */
91 #define UCEBCDIC 24 /* convert ASCII to upper case blocked EBCDIC */
92 #define IBM 25 /* convert ASCII to blocked IBM */
93 #define LCIBM 26 /* convert ASCII to lower case blocked IBM */
94 #define UCIBM 27 /* convert ASCII to upper case blocked IBM */
95 #define LCASE 01 /* flag - convert to lower case */
96 #define UCASE 02 /* flag - convert to upper case */
97 #define SWAB 04 /* flag - swap bytes before conversion */
98 #define NERR 010 /* flag - proceed on input errors */
99 #define SYNC 020 /* flag - pad short input blocks with nulls */
100 #define BADLIMIT 5 /* give up if no progress after BADLIMIT trys */
101 #define SVR4XLATE 0 /* use default EBCDIC translation */
102 #define BSDXLATE 1 /* use BSD-compatible EBCDIC translation */
104 #define USAGE\
105 "usage: dd [if=file] [of=file] [ibs=n|nk|nb|nxm] [obs=n|nk|nb|nxm]\n"\
106 " [bs=n|nk|nb|nxm] [cbs=n|nk|nb|nxm] [files=n] [skip=n]\n"\
107 " [iseek=n] [oseek=n] [seek=n] [stride=n] [istride=n]\n"\
108 " [ostride=n] [count=n] [conv=[ascii] [,ebcdic][,ibm]\n"\
109 " [,asciib][,ebcdicb][,ibmb][,block|unblock][,lcase|ucase]\n"\
110 " [,swab][,noerror][,notrunc][,sync]]\n"\
111 " [oflag=[dsync][sync]]\n"
113 /* Global references */
115 /* Local routine declarations */
117 static int match(char *);
118 static void term();
119 static unsigned long long number();
120 static unsigned char *flsh();
121 static void stats();
123 /* Local data definitions */
125 static unsigned ibs; /* input buffer size */
126 static unsigned obs; /* output buffer size */
127 static unsigned bs; /* buffer size, overrules ibs and obs */
128 static unsigned cbs; /* conversion buffer size, used for block conversions */
129 static unsigned ibc; /* number of bytes still in the input buffer */
130 static unsigned obc; /* number of bytes in the output buffer */
131 static unsigned cbc; /* number of bytes in the conversion buffer */
133 static int ibf; /* input file descriptor */
134 static int obf; /* output file descriptor */
135 static int cflag; /* conversion option flags */
136 static int oflag; /* output flag options */
137 static int skipf; /* if skipf == 1, skip rest of input line */
138 static unsigned long long nifr; /* count of full input records */
139 static unsigned long long nipr; /* count of partial input records */
140 static unsigned long long nofr; /* count of full output records */
141 static unsigned long long nopr; /* count of partial output records */
142 static unsigned long long ntrunc; /* count of truncated input lines */
143 static unsigned long long nbad; /* count of bad records since last */
144 /* good one */
145 static int files; /* number of input files to concatenate (tape only) */
146 static off_t skip; /* number of input records to skip */
147 static off_t iseekn; /* number of input records to seek past */
148 static off_t oseekn; /* number of output records to seek past */
149 static unsigned long long count; /* number of input records to copy */
150 /* (0 = all) */
151 static boolean_t ecount; /* explicit count given */
152 static off_t ostriden; /* number of output blocks to skip between */
153 /* records */
154 static off_t istriden; /* number of input blocks to skip between */
155 /* records */
157 static int trantype; /* BSD or SVr4 compatible EBCDIC */
159 static char *string; /* command arg pointer */
160 static char *ifile; /* input file name pointer */
161 static char *ofile; /* output file name pointer */
162 static unsigned char *ibuf; /* input buffer pointer */
163 static unsigned char *obuf; /* output buffer pointer */
165 static hrtime_t startt; /* hrtime copy started */
166 static unsigned long long obytes; /* output bytes */
167 static sig_atomic_t nstats; /* do we need to output stats */
169 /* This is an EBCDIC to ASCII conversion table */
170 /* from a proposed BTL standard April 16, 1979 */
172 static unsigned char svr4_etoa [] =
174 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
175 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
176 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
177 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
178 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
179 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
180 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
181 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
182 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
183 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
184 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
185 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
186 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
187 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
188 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
189 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
190 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
191 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
192 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
193 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
194 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
195 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
196 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
197 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
198 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
199 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
200 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
201 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
202 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
203 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
204 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
205 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
208 /* This is an ASCII to EBCDIC conversion table */
209 /* from a proposed BTL standard April 16, 1979 */
211 static unsigned char svr4_atoe [] =
213 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
214 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
215 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
216 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
217 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
218 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
219 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
220 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
221 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
222 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
223 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
224 0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155,
225 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
226 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
227 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
228 0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007,
229 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
230 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
231 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
232 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
233 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
234 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
235 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
236 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
237 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
238 0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236,
239 0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257,
240 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
241 0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277,
242 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
243 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
244 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
247 /* Table for ASCII to IBM (alternate EBCDIC) code conversion */
249 static unsigned char svr4_atoibm[] =
251 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
252 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
253 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
254 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
255 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
256 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
257 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
258 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
259 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
260 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
261 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
262 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
263 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
264 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
265 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
266 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
267 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
268 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
269 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
270 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
271 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
272 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
273 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
274 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
275 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
276 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
277 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
278 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
279 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
280 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
281 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
282 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
285 /* Table for conversion of ASCII to lower case ASCII */
287 static unsigned char utol[] =
289 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
290 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
291 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
292 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
293 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
294 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
295 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
296 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
297 0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
298 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
299 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
300 0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
301 0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
302 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
303 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
304 0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
305 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
306 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
307 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
308 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
309 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
310 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
311 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
312 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
313 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
314 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
315 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
316 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
317 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
318 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
319 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
320 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
323 /* Table for conversion of ASCII to upper case ASCII */
325 static unsigned char ltou[] =
327 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
328 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
329 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
330 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
331 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
332 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
333 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
334 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
335 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
336 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
337 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
338 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
339 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
340 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
341 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
342 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
343 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
344 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
345 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
346 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
347 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
348 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
349 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
350 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
351 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
352 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
353 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
354 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
355 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
356 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
357 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
358 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
361 /* BSD-compatible EBCDIC to ASCII translate table */
363 static unsigned char bsd_etoa[] =
365 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
366 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
367 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
368 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
369 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
370 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
371 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
372 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
373 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
374 0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041,
375 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
376 0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136,
377 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
378 0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077,
379 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
380 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
381 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
382 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
383 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
384 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
385 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
386 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
387 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
388 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
389 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
390 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
391 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
392 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
393 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
394 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
395 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
396 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
399 /* BSD-compatible ASCII to EBCDIC translate table */
401 static unsigned char bsd_atoe[] =
403 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
404 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
405 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
406 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
407 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
408 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
409 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
410 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
411 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
412 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
413 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
414 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
415 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
416 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
417 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
418 0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007,
419 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
420 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
421 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
422 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
423 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
424 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
425 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
426 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
427 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
428 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
429 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
430 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
431 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
432 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
433 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
434 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
437 /* BSD-compatible ASCII to IBM translate table */
439 static unsigned char bsd_atoibm[] =
441 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
442 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
443 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
444 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
445 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
446 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
447 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
448 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
449 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
450 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
451 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
452 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
453 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
454 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
455 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
456 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
457 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
458 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
459 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
460 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
461 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
462 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
463 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
464 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
465 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
466 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
467 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
468 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
469 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
470 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
471 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
472 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
475 /* set up to use SVr4 ascii-ebcdic translation by default */
477 static unsigned char *atoe = svr4_atoe;
478 static unsigned char *etoa = svr4_etoa;
479 static unsigned char *atoibm = svr4_atoibm;
481 /*ARGSUSED*/
482 static void
483 siginfo_handler(int sig, siginfo_t *sip, void *ucp)
485 nstats = 1;
489 main(int argc, char **argv)
491 unsigned char *ip, *op; /* input and output buffer pointers */
492 int c; /* character counter */
493 int ic; /* input character */
494 int conv; /* conversion option code */
495 int trunc; /* whether output file is truncated */
496 struct stat file_stat;
497 struct sigaction sact;
499 /* Set option defaults */
501 ibs = BSIZE;
502 obs = BSIZE;
503 files = 1;
504 conv = COPY;
505 trunc = 1; /* default: truncate output file */
506 trantype = SVR4XLATE; /* use SVR4 EBCDIC by default */
508 /* Parse command options */
510 (void) setlocale(LC_ALL, "");
511 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
512 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
513 #endif
514 (void) textdomain(TEXT_DOMAIN);
516 while ((c = getopt(argc, argv, "")) != EOF)
517 switch (c) {
518 case '?':
519 (void) fprintf(stderr, USAGE);
520 exit(2);
523 /* not getopt()'ed because dd has no options but only operand(s) */
525 for (c = optind; c < argc; c++)
527 string = argv[c];
528 if (match("ibs="))
530 ibs = (unsigned)number(BIG);
531 continue;
533 if (match("obs="))
535 obs = (unsigned)number(BIG);
536 continue;
538 if (match("cbs="))
540 cbs = (unsigned)number(BIG);
541 continue;
543 if (match("bs="))
545 bs = (unsigned)number(BIG);
546 continue;
548 if (match("if="))
550 ifile = string;
551 continue;
553 if (match("of="))
555 ofile = string;
556 continue;
558 if (match("skip="))
560 skip = number(BIG);
561 continue;
563 if (match("iseek="))
565 iseekn = number(BIG);
566 continue;
568 if (match("oseek="))
570 oseekn = number(BIG);
571 continue;
573 if (match("seek=")) /* retained for compatibility */
575 oseekn = number(BIG);
576 continue;
578 if (match("ostride="))
580 ostriden = ((off_t)number(BIG)) - 1;
581 continue;
583 if (match("istride="))
585 istriden = ((off_t)number(BIG)) - 1;
586 continue;
588 if (match("stride="))
590 istriden = ostriden = ((off_t)number(BIG)) - 1;
591 continue;
593 if (match("count="))
595 count = number(BIG);
596 ecount = B_TRUE;
597 continue;
599 if (match("files="))
601 files = (int)number(BIG);
602 continue;
604 if (match("conv="))
606 for (;;)
608 if (match(","))
610 continue;
612 if (*string == '\0')
614 break;
616 if (match("block"))
618 conv = BLOCK;
619 continue;
621 if (match("unblock"))
623 conv = UNBLOCK;
624 continue;
627 /* ebcdicb, ibmb, and asciib must precede */
628 /* ebcdic, ibm, and ascii in this test */
630 if (match("ebcdicb"))
632 conv = EBCDIC;
633 trantype = BSDXLATE;
634 continue;
636 if (match("ibmb"))
638 conv = IBM;
639 trantype = BSDXLATE;
640 continue;
642 if (match("asciib"))
644 conv = ASCII;
645 trantype = BSDXLATE;
646 continue;
648 if (match("ebcdic"))
650 conv = EBCDIC;
651 trantype = SVR4XLATE;
652 continue;
654 if (match("ibm"))
656 conv = IBM;
657 trantype = SVR4XLATE;
658 continue;
660 if (match("ascii"))
662 conv = ASCII;
663 trantype = SVR4XLATE;
664 continue;
666 if (match("lcase"))
668 cflag |= LCASE;
669 continue;
671 if (match("ucase"))
673 cflag |= UCASE;
674 continue;
676 if (match("swab"))
678 cflag |= SWAB;
679 continue;
681 if (match("noerror"))
683 cflag |= NERR;
684 continue;
686 if (match("notrunc"))
688 trunc = 0;
689 continue;
691 if (match("sync"))
693 cflag |= SYNC;
694 continue;
696 goto badarg;
698 continue;
700 if (match("oflag="))
702 for (;;)
704 if (match(","))
706 continue;
708 if (*string == '\0')
710 break;
712 if (match("dsync"))
714 oflag |= O_DSYNC;
715 continue;
717 if (match("sync"))
719 oflag |= O_SYNC;
720 continue;
722 goto badarg;
724 continue;
726 badarg:
727 (void) fprintf(stderr, "dd: %s \"%s\"\n",
728 gettext("bad argument:"), string);
729 exit(2);
732 /* Perform consistency checks on options, decode strange conventions */
734 if (bs)
736 ibs = obs = bs;
738 if ((ibs == 0) || (obs == 0))
740 (void) fprintf(stderr, "dd: %s\n",
741 gettext("buffer sizes cannot be zero"));
742 exit(2);
744 if (ostriden == (off_t)-1) {
745 (void) fprintf(stderr, "dd: %s\n",
746 gettext("stride must be greater than zero"));
747 exit(2);
749 if (istriden == (off_t)-1) {
750 (void) fprintf(stderr, "dd: %s\n",
751 gettext("stride must be greater than zero"));
752 exit(2);
754 if (conv == COPY)
756 if ((bs == 0) || (cflag&(LCASE|UCASE)))
758 conv = REBLOCK;
761 if (cbs == 0)
763 switch (conv)
765 case BLOCK:
766 case UNBLOCK:
767 conv = REBLOCK;
768 break;
770 case ASCII:
771 conv = NBASCII;
772 break;
774 case EBCDIC:
775 conv = NBEBCDIC;
776 break;
778 case IBM:
779 conv = NBIBM;
780 break;
784 /* Expand options into lower and upper case versions if necessary */
786 switch (conv)
788 case REBLOCK:
789 if (cflag&LCASE)
790 conv = LCREBLOCK;
791 else if (cflag&UCASE)
792 conv = UCREBLOCK;
793 break;
795 case UNBLOCK:
796 if (cflag&LCASE)
797 conv = LCUNBLOCK;
798 else if (cflag&UCASE)
799 conv = UCUNBLOCK;
800 break;
802 case BLOCK:
803 if (cflag&LCASE)
804 conv = LCBLOCK;
805 else if (cflag&UCASE)
806 conv = UCBLOCK;
807 break;
809 case ASCII:
810 if (cflag&LCASE)
811 conv = LCASCII;
812 else if (cflag&UCASE)
813 conv = UCASCII;
814 break;
816 case NBASCII:
817 if (cflag&LCASE)
818 conv = LCNBASCII;
819 else if (cflag&UCASE)
820 conv = UCNBASCII;
821 break;
823 case EBCDIC:
824 if (cflag&LCASE)
825 conv = LCEBCDIC;
826 else if (cflag&UCASE)
827 conv = UCEBCDIC;
828 break;
830 case NBEBCDIC:
831 if (cflag&LCASE)
832 conv = LCNBEBCDIC;
833 else if (cflag&UCASE)
834 conv = UCNBEBCDIC;
835 break;
837 case IBM:
838 if (cflag&LCASE)
839 conv = LCIBM;
840 else if (cflag&UCASE)
841 conv = UCIBM;
842 break;
844 case NBIBM:
845 if (cflag&LCASE)
846 conv = LCNBIBM;
847 else if (cflag&UCASE)
848 conv = UCNBIBM;
849 break;
852 /* If BSD-compatible translation is selected, change the tables */
854 if (trantype == BSDXLATE) {
855 atoe = bsd_atoe;
856 atoibm = bsd_atoibm;
857 etoa = bsd_etoa;
859 /* Open the input file, or duplicate standard input */
861 ibf = -1;
862 if (ifile)
864 ibf = open(ifile, O_RDONLY);
866 else
868 ifile = "";
869 ibf = dup(0);
872 if (ibf == -1)
874 (void) fprintf(stderr, "dd: %s: ", ifile);
875 perror("open");
876 exit(2);
879 /* Open the output file, or duplicate standard output */
881 obf = -1;
882 if (ofile)
884 if (trunc == 0) /* do not truncate output file */
885 obf = open(ofile, (O_WRONLY|O_CREAT|oflag),
886 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
887 else if (oseekn && (trunc == 1))
889 obf = open(ofile, O_WRONLY|O_CREAT|oflag,
890 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
891 if (obf == -1)
893 (void) fprintf(stderr, "dd: %s: ", ofile);
894 perror("open");
895 exit(2);
897 (void) fstat(obf, &file_stat);
898 if (((file_stat.st_mode & S_IFMT) == S_IFREG) &&
899 (ftruncate(obf, (((off_t)oseekn) * ((off_t)obs)))
900 == -1))
902 perror("ftruncate");
903 exit(2);
906 else
907 obf = open(ofile, O_WRONLY|O_CREAT|O_TRUNC|oflag,
908 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
910 else
912 ofile = "";
913 obf = dup(1);
916 if (obf == -1)
918 (void) fprintf(stderr, "dd: %s: ", ofile);
919 perror("open");
920 exit(2);
923 /* Expand memory to get an input buffer */
925 ibuf = (unsigned char *)valloc(ibs + 10);
927 /* If no conversions, the input buffer is the output buffer */
929 if (conv == COPY)
931 obuf = ibuf;
934 /* Expand memory to get an output buffer. Leave enough room at the */
935 /* end to convert a logical record when doing block conversions. */
937 else
939 obuf = (unsigned char *)valloc(obs + cbs + 10);
941 if ((ibuf == (unsigned char *)NULL) || (obuf == (unsigned char *)NULL))
943 (void) fprintf(stderr,
944 "dd: %s\n", gettext("not enough memory"));
945 exit(2);
949 * Enable a statistics message when we terminate on SIGINT
950 * Also enable it to be queried via SIGINFO and SIGUSR1
953 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
955 (void) signal(SIGINT, term);
958 bzero(&sact, sizeof (struct sigaction));
959 sact.sa_flags = SA_SIGINFO;
960 sact.sa_sigaction = siginfo_handler;
961 (void) sigemptyset(&sact.sa_mask);
962 if (sigaction(SIGINFO, &sact, NULL) != 0) {
963 (void) fprintf(stderr, "dd: %s: %s\n",
964 gettext("failed to enable siginfo handler"),
965 gettext(strerror(errno)));
966 exit(2);
968 if (sigaction(SIGUSR1, &sact, NULL) != 0) {
969 (void) fprintf(stderr, "dd: %s: %s\n",
970 gettext("failed to enable sigusr1 handler"),
971 gettext(strerror(errno)));
972 exit(2);
975 /* Skip input blocks */
977 while (skip)
979 ibc = read(ibf, (char *)ibuf, ibs);
980 if (ibc == (unsigned)-1)
982 if (++nbad > BADLIMIT)
984 (void) fprintf(stderr, "dd: %s\n",
985 gettext("skip failed"));
986 exit(2);
988 else
990 perror("read");
993 else
995 if (ibc == 0)
997 (void) fprintf(stderr, "dd: %s\n",
998 gettext("cannot skip past end-of-file"));
999 exit(3);
1001 else
1003 nbad = 0;
1006 skip--;
1009 /* Seek past input blocks */
1011 if (iseekn && lseek(ibf, (((off_t)iseekn) * ((off_t)ibs)), 1) == -1)
1013 perror("lseek");
1014 exit(2);
1017 /* Seek past output blocks */
1019 if (oseekn && lseek(obf, (((off_t)oseekn) * ((off_t)obs)), 1) == -1)
1021 perror("lseek");
1022 exit(2);
1025 /* Initialize all buffer pointers */
1027 skipf = 0; /* not skipping an input line */
1028 ibc = 0; /* no input characters yet */
1029 obc = 0; /* no output characters yet */
1030 cbc = 0; /* the conversion buffer is empty */
1031 op = obuf; /* point to the output buffer */
1033 /* Read and convert input blocks until end of file(s) */
1035 /* Grab our start time for siginfo purposes */
1036 startt = gethrtime();
1038 for (;;)
1040 if (nstats != 0) {
1041 stats();
1042 nstats = 0;
1045 if ((count == 0 && ecount == B_FALSE) || (nifr+nipr < count)) {
1046 /* If proceed on error is enabled, zero the input buffer */
1048 if (cflag&NERR)
1050 ip = ibuf + ibs;
1051 c = ibs;
1052 if (c & 1) /* if the size is odd, */
1054 *--ip = 0; /* clear the odd byte */
1056 if (c >>= 1) /* divide by two */
1058 do { /* clear two at a time */
1059 *--ip = 0;
1060 *--ip = 0;
1061 } while (--c);
1065 /* Read the next input block */
1067 ibc = read(ibf, (char *)ibuf, ibs);
1069 if (istriden > 0 && lseek(ibf, istriden * ((off_t)ibs),
1070 SEEK_CUR) == -1) {
1071 perror("lseek");
1072 exit(2);
1075 /* Process input errors */
1077 if (ibc == (unsigned)-1)
1079 perror("read");
1080 if (((cflag&NERR) == 0) || (++nbad > BADLIMIT))
1082 while (obc)
1084 (void) flsh();
1086 term(2);
1088 else
1090 stats();
1091 ibc = ibs; /* assume a full block */
1094 else
1096 nbad = 0;
1100 /* Record count satisfied, simulate end of file */
1102 else
1104 ibc = 0;
1105 files = 1;
1108 /* Process end of file */
1110 if (ibc == 0)
1112 switch (conv)
1114 case UNBLOCK:
1115 case LCUNBLOCK:
1116 case UCUNBLOCK:
1117 case ASCII:
1118 case LCASCII:
1119 case UCASCII:
1121 /* Trim trailing blanks from the last line */
1123 if ((c = cbc) != 0)
1125 do {
1126 if ((*--op) != ' ')
1128 op++;
1129 break;
1131 } while (--c);
1132 *op++ = '\n';
1133 obc -= cbc - c - 1;
1134 cbc = 0;
1136 /* Flush the output buffer if full */
1138 while (obc >= obs)
1140 op = flsh();
1143 break;
1145 case BLOCK:
1146 case LCBLOCK:
1147 case UCBLOCK:
1148 case EBCDIC:
1149 case LCEBCDIC:
1150 case UCEBCDIC:
1151 case IBM:
1152 case LCIBM:
1153 case UCIBM:
1155 /* Pad trailing blanks if the last line is short */
1157 if (cbc)
1159 obc += c = cbs - cbc;
1160 cbc = 0;
1161 if (c > 0)
1163 /* Use the right kind of blank */
1165 switch (conv)
1167 case BLOCK:
1168 case LCBLOCK:
1169 case UCBLOCK:
1170 ic = ' ';
1171 break;
1173 case EBCDIC:
1174 case LCEBCDIC:
1175 case UCEBCDIC:
1176 ic = atoe[' '];
1177 break;
1179 case IBM:
1180 case LCIBM:
1181 case UCIBM:
1182 ic = atoibm[' '];
1183 break;
1186 /* Pad with trailing blanks */
1188 do {
1189 *op++ = ic;
1190 } while (--c);
1195 /* Flush the output buffer if full */
1197 while (obc >= obs)
1199 op = flsh();
1201 break;
1204 /* If no more files to read, flush the output buffer */
1206 if (--files <= 0)
1208 (void) flsh();
1209 if ((close(obf) != 0) || (fclose(stdout) != 0))
1211 perror(gettext("dd: close error"));
1212 exit(2);
1214 term(0); /* successful exit */
1216 else
1218 continue; /* read the next file */
1222 /* Normal read, check for special cases */
1224 else if (ibc == ibs)
1226 nifr++; /* count another full input record */
1228 else
1230 nipr++; /* count a partial input record */
1232 /* If `sync' enabled, pad nulls */
1234 if ((cflag&SYNC) && ((cflag&NERR) == 0))
1236 c = ibs - ibc;
1237 ip = ibuf + ibs;
1238 do {
1239 if ((conv == BLOCK) || (conv == UNBLOCK))
1240 *--ip = ' ';
1241 else
1242 *--ip = '\0';
1243 } while (--c);
1244 ibc = ibs;
1248 /* Swap the bytes in the input buffer if necessary */
1250 if (cflag&SWAB)
1252 ip = ibuf;
1253 if (ibc & 1) /* if the byte count is odd, */
1255 ip[ibc] = 0; /* make it even, pad with zero */
1257 c = ibc >> 1; /* compute the pair count */
1258 do {
1259 ic = *ip++;
1260 ip[-1] = *ip;
1261 *ip++ = ic;
1262 } while (--c); /* do two bytes at a time */
1265 /* Select the appropriate conversion loop */
1267 ip = ibuf;
1268 switch (conv)
1271 /* Simple copy: no conversion, preserve the input block size */
1273 case COPY:
1274 obc = ibc;
1275 (void) flsh();
1276 break;
1278 /* Simple copy: pack all output into equal sized blocks */
1280 case REBLOCK:
1281 case LCREBLOCK:
1282 case UCREBLOCK:
1283 case NBASCII:
1284 case LCNBASCII:
1285 case UCNBASCII:
1286 case NBEBCDIC:
1287 case LCNBEBCDIC:
1288 case UCNBEBCDIC:
1289 case NBIBM:
1290 case LCNBIBM:
1291 case UCNBIBM:
1292 while ((c = ibc) != 0)
1294 if (c > (obs - obc))
1296 c = obs - obc;
1298 ibc -= c;
1299 obc += c;
1300 switch (conv)
1302 case REBLOCK:
1303 do {
1304 *op++ = *ip++;
1305 } while (--c);
1306 break;
1308 case LCREBLOCK:
1309 do {
1310 *op++ = utol[*ip++];
1311 } while (--c);
1312 break;
1314 case UCREBLOCK:
1315 do {
1316 *op++ = ltou[*ip++];
1317 } while (--c);
1318 break;
1320 case NBASCII:
1321 do {
1322 *op++ = etoa[*ip++];
1323 } while (--c);
1324 break;
1326 case LCNBASCII:
1327 do {
1328 *op++ = utol[etoa[*ip++]];
1329 } while (--c);
1330 break;
1332 case UCNBASCII:
1333 do {
1334 *op++ = ltou[etoa[*ip++]];
1335 } while (--c);
1336 break;
1338 case NBEBCDIC:
1339 do {
1340 *op++ = atoe[*ip++];
1341 } while (--c);
1342 break;
1344 case LCNBEBCDIC:
1345 do {
1346 *op++ = atoe[utol[*ip++]];
1347 } while (--c);
1348 break;
1350 case UCNBEBCDIC:
1351 do {
1352 *op++ = atoe[ltou[*ip++]];
1353 } while (--c);
1354 break;
1356 case NBIBM:
1357 do {
1358 *op++ = atoibm[*ip++];
1359 } while (--c);
1360 break;
1362 case LCNBIBM:
1363 do {
1364 *op++ = atoibm[utol[*ip++]];
1365 } while (--c);
1366 break;
1368 case UCNBIBM:
1369 do {
1370 *op++ = atoibm[ltou[*ip++]];
1371 } while (--c);
1372 break;
1374 if (obc >= obs)
1376 op = flsh();
1379 break;
1381 /* Convert from blocked records to lines terminated by newline */
1383 case UNBLOCK:
1384 case LCUNBLOCK:
1385 case UCUNBLOCK:
1386 case ASCII:
1387 case LCASCII:
1388 case UCASCII:
1389 while ((c = ibc) != 0)
1391 if (c > (cbs - cbc))
1392 /* if more than one record, */
1394 c = cbs - cbc;
1395 /* only copy one record */
1397 ibc -= c;
1398 cbc += c;
1399 obc += c;
1400 switch (conv)
1402 case UNBLOCK:
1403 do {
1404 *op++ = *ip++;
1405 } while (--c);
1406 break;
1408 case LCUNBLOCK:
1409 do {
1410 *op++ = utol[*ip++];
1411 } while (--c);
1412 break;
1414 case UCUNBLOCK:
1415 do {
1416 *op++ = ltou[*ip++];
1417 } while (--c);
1418 break;
1420 case ASCII:
1421 do {
1422 *op++ = etoa[*ip++];
1423 } while (--c);
1424 break;
1426 case LCASCII:
1427 do {
1428 *op++ = utol[etoa[*ip++]];
1429 } while (--c);
1430 break;
1432 case UCASCII:
1433 do {
1434 *op++ = ltou[etoa[*ip++]];
1435 } while (--c);
1436 break;
1439 /* Trim trailing blanks if the line is full */
1441 if (cbc == cbs)
1443 c = cbs; /* `do - while' is usually */
1444 do { /* faster than `for' */
1445 if ((*--op) != ' ')
1447 op++;
1448 break;
1450 } while (--c);
1451 *op++ = '\n';
1452 obc -= cbs - c - 1;
1453 cbc = 0;
1455 /* Flush the output buffer if full */
1457 while (obc >= obs)
1459 op = flsh();
1463 break;
1465 /* Convert to blocked records */
1467 case BLOCK:
1468 case LCBLOCK:
1469 case UCBLOCK:
1470 case EBCDIC:
1471 case LCEBCDIC:
1472 case UCEBCDIC:
1473 case IBM:
1474 case LCIBM:
1475 case UCIBM:
1476 while ((c = ibc) != 0)
1478 int nlflag = 0;
1480 /* We may have to skip to the end of a long line */
1482 if (skipf)
1484 do {
1485 if ((ic = *ip++) == '\n')
1487 skipf = 0;
1488 c--;
1489 break;
1491 } while (--c);
1492 if ((ibc = c) == 0)
1494 continue;
1495 /* read another block */
1499 /* If anything left, copy until newline */
1501 if (c > (cbs - cbc + 1))
1503 c = cbs - cbc + 1;
1505 ibc -= c;
1506 cbc += c;
1507 obc += c;
1509 switch (conv)
1511 case BLOCK:
1512 do {
1513 if ((ic = *ip++) != '\n')
1515 *op++ = ic;
1517 else
1519 nlflag = 1;
1520 break;
1522 } while (--c);
1523 break;
1525 case LCBLOCK:
1526 do {
1527 if ((ic = *ip++) != '\n')
1529 *op++ = utol[ic];
1531 else
1533 nlflag = 1;
1534 break;
1536 } while (--c);
1537 break;
1539 case UCBLOCK:
1540 do {
1541 if ((ic = *ip++) != '\n')
1543 *op++ = ltou[ic];
1545 else
1547 nlflag = 1;
1548 break;
1550 } while (--c);
1551 break;
1553 case EBCDIC:
1554 do {
1555 if ((ic = *ip++) != '\n')
1557 *op++ = atoe[ic];
1559 else
1561 nlflag = 1;
1562 break;
1564 } while (--c);
1565 break;
1567 case LCEBCDIC:
1568 do {
1569 if ((ic = *ip++) != '\n')
1571 *op++ = atoe[utol[ic]];
1573 else
1575 nlflag = 1;
1576 break;
1578 } while (--c);
1579 break;
1581 case UCEBCDIC:
1582 do {
1583 if ((ic = *ip++) != '\n')
1585 *op++ = atoe[ltou[ic]];
1587 else
1589 nlflag = 1;
1590 break;
1592 } while (--c);
1593 break;
1595 case IBM:
1596 do {
1597 if ((ic = *ip++) != '\n')
1599 *op++ = atoibm[ic];
1601 else
1603 nlflag = 1;
1604 break;
1606 } while (--c);
1607 break;
1609 case LCIBM:
1610 do {
1611 if ((ic = *ip++) != '\n')
1613 *op++ = atoibm[utol[ic]];
1615 else
1617 nlflag = 1;
1618 break;
1620 } while (--c);
1621 break;
1623 case UCIBM:
1624 do {
1625 if ((ic = *ip++) != '\n')
1627 *op++ = atoibm[ltou[ic]];
1629 else
1631 nlflag = 1;
1632 break;
1634 } while (--c);
1635 break;
1638 /* If newline found, update all the counters and */
1639 /* pointers, pad with trailing blanks if necessary */
1641 if (nlflag)
1643 ibc += c - 1;
1644 obc += cbs - cbc;
1645 c += cbs - cbc;
1646 cbc = 0;
1647 if (c > 0)
1649 /* Use the right kind of blank */
1651 switch (conv)
1653 case BLOCK:
1654 case LCBLOCK:
1655 case UCBLOCK:
1656 ic = ' ';
1657 break;
1659 case EBCDIC:
1660 case LCEBCDIC:
1661 case UCEBCDIC:
1662 ic = atoe[' '];
1663 break;
1665 case IBM:
1666 case LCIBM:
1667 case UCIBM:
1668 ic = atoibm[' '];
1669 break;
1672 /* Pad with trailing blanks */
1674 do {
1675 *op++ = ic;
1676 } while (--c);
1680 /* If not end of line, this line may be too long */
1682 else if (cbc > cbs)
1684 skipf = 1; /* note skip in progress */
1685 obc--;
1686 op--;
1687 cbc = 0;
1688 ntrunc++; /* count another long line */
1691 /* Flush the output buffer if full */
1693 while (obc >= obs)
1695 op = flsh();
1698 break;
1701 /* NOTREACHED */
1702 return (0);
1705 /* match ************************************************************** */
1706 /* */
1707 /* Compare two text strings for equality */
1708 /* */
1709 /* Arg: s - pointer to string to match with a command arg */
1710 /* Global arg: string - pointer to command arg */
1711 /* */
1712 /* Return: 1 if match, 0 if no match */
1713 /* If match, also reset `string' to point to the text */
1714 /* that follows the matching text. */
1715 /* */
1716 /* ******************************************************************** */
1718 static int
1719 match(s)
1720 char *s;
1722 char *cs;
1724 cs = string;
1725 while (*cs++ == *s)
1727 if (*s++ == '\0')
1729 goto true;
1732 if (*s != '\0')
1734 return (0);
1737 true:
1738 cs--;
1739 string = cs;
1740 return (1);
1743 /* number ************************************************************* */
1744 /* */
1745 /* Convert a numeric arg to binary */
1746 /* */
1747 /* Arg: big - maximum valid input number */
1748 /* Global arg: string - pointer to command arg */
1749 /* */
1750 /* Valid forms: 123 | 123k | 123M | 123G | 123T | 123P | 123E | 123Z | */
1751 /* 123w | 123b | 123*123 | 123x123 */
1752 /* plus combinations such as 2b*3kw*4w */
1753 /* */
1754 /* Return: converted number */
1755 /* */
1756 /* ******************************************************************** */
1758 static unsigned long long
1759 number(big)
1760 long long big;
1762 char *cs;
1763 long long n;
1764 long long cut = BIG / 10; /* limit to avoid overflow */
1766 cs = string;
1767 n = 0;
1768 while ((*cs >= '0') && (*cs <= '9') && (n <= cut))
1770 n = n*10 + *cs++ - '0';
1772 for (;;)
1774 switch (*cs++)
1777 case 'Z':
1778 n *= 1024;
1779 /* FALLTHROUGH */
1781 case 'E':
1782 n *= 1024;
1783 /* FALLTHROUGH */
1785 case 'P':
1786 n *= 1024;
1787 /* FALLTHROUGH */
1789 case 'T':
1790 n *= 1024;
1791 /* FALLTHROUGH */
1793 case 'G':
1794 n *= 1024;
1795 /* FALLTHROUGH */
1797 case 'M':
1798 n *= 1024;
1799 /* FALLTHROUGH */
1801 case 'k':
1802 n *= 1024;
1803 continue;
1805 case 'w':
1806 n *= 2;
1807 continue;
1809 case 'b':
1810 n *= BSIZE;
1811 continue;
1813 case '*':
1814 case 'x':
1815 string = cs;
1816 n *= number(BIG);
1818 /* FALLTHROUGH */
1819 /* Fall into exit test, recursion has read rest of string */
1820 /* End of string, check for a valid number */
1822 case '\0':
1823 if ((n > big) || (n < 0))
1825 (void) fprintf(stderr, "dd: %s \"%llu\"\n",
1826 gettext("argument out of range:"), n);
1827 exit(2);
1829 return (n);
1831 default:
1832 (void) fprintf(stderr, "dd: %s \"%s\"\n",
1833 gettext("bad numeric argument:"), string);
1834 exit(2);
1836 } /* never gets here */
1839 /* flsh *************************************************************** */
1840 /* */
1841 /* Flush the output buffer, move any excess bytes down to the beginning */
1842 /* */
1843 /* Arg: none */
1844 /* Global args: obuf, obc, obs, nofr, nopr, ostriden */
1845 /* */
1846 /* Return: Pointer to the first free byte in the output buffer. */
1847 /* Also reset `obc' to account for moved bytes. */
1848 /* */
1849 /* ******************************************************************** */
1851 static unsigned char
1852 *flsh()
1854 unsigned char *op, *cp;
1855 int bc;
1856 unsigned int oc;
1858 if (obc) /* don't flush if the buffer is empty */
1860 if (obc >= obs) {
1861 oc = obs;
1862 nofr++; /* count a full output buffer */
1864 else
1866 oc = obc;
1867 nopr++; /* count a partial output buffer */
1869 bc = write(obf, (char *)obuf, oc);
1870 if (bc != oc) {
1871 if (bc < 0)
1872 perror("write");
1873 else
1874 (void) fprintf(stderr,
1875 gettext("dd: unexpected short write, "
1876 "wrote %d bytes, expected %d\n"), bc, oc);
1877 term(2);
1880 if (ostriden > 0 && lseek(obf, ostriden * ((off_t)obs),
1881 SEEK_CUR) == -1) {
1882 perror("lseek");
1883 exit(2);
1886 obc -= oc;
1887 op = obuf;
1888 obytes += bc;
1890 /* If any data in the conversion buffer, move it into */
1891 /* the output buffer */
1893 if (obc) {
1894 cp = obuf + obs;
1895 bc = obc;
1896 do {
1897 *op++ = *cp++;
1898 } while (--bc);
1900 return (op);
1902 return (obuf);
1905 /* term *************************************************************** */
1906 /* */
1907 /* Write record statistics, then exit */
1908 /* */
1909 /* Arg: c - exit status code */
1910 /* */
1911 /* Return: no return, calls exit */
1912 /* */
1913 /* ******************************************************************** */
1915 static void
1916 term(c)
1917 int c;
1919 stats();
1920 exit(c);
1923 /* stats ************************************************************** */
1924 /* */
1925 /* Write record statistics onto standard error */
1926 /* */
1927 /* Args: none */
1928 /* Global args: nifr, nipr, nofr, nopr, ntrunc */
1929 /* */
1930 /* Return: void */
1931 /* */
1932 /* ******************************************************************** */
1934 static void
1935 stats()
1937 hrtime_t delta = gethrtime() - startt;
1938 double secs = delta * 1e-9;
1940 (void) fprintf(stderr, gettext("%llu+%llu records in\n"), nifr, nipr);
1941 (void) fprintf(stderr, gettext("%llu+%llu records out\n"), nofr, nopr);
1942 if (ntrunc) {
1943 (void) fprintf(stderr,
1944 gettext("%llu truncated record(s)\n"), ntrunc);
1948 * If we got here before we started copying somehow, don't bother
1949 * printing the rest.
1951 if (startt == 0)
1952 return;
1954 (void) fprintf(stderr,
1955 gettext("%llu bytes transferred in %.6f secs (%.0f bytes/sec)\n"),
1956 obytes, secs, obytes / secs);