2831 bring Joyent/SmartOS OS-1186 and OS-1187 to Illumos (fix lint, copyright)
[illumos-gate.git] / usr / src / cmd / dd / dd.c
blob75caccbeac505920de37d8f6d8d5d0d163f79d44
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.
29 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
30 /* All Rights Reserved */
33 * convert and copy
36 #include <stdio.h>
37 #include <signal.h>
38 #include <fcntl.h>
39 #include <sys/param.h>
40 #include <sys/types.h>
41 #include <sys/sysmacros.h>
42 #include <sys/stat.h>
43 #include <unistd.h>
44 #include <stdlib.h>
45 #include <locale.h>
46 #include <string.h>
48 /* The BIG parameter is machine dependent. It should be a long integer */
49 /* constant that can be used by the number parser to check the validity */
50 /* of numeric parameters. On 16-bit machines, it should probably be */
51 /* the maximum unsigned integer, 0177777L. On 32-bit machines where */
52 /* longs are the same size as ints, the maximum signed integer is more */
53 /* appropriate. This value is 017777777777L. In 64 bit environments, */
54 /* the maximum signed integer value is 0777777777777777777777LL */
56 #define BIG 0777777777777777777777LL
58 #define BSIZE 512
60 /* Option parameters */
62 #define COPY 0 /* file copy, preserve input block size */
63 #define REBLOCK 1 /* file copy, change block size */
64 #define LCREBLOCK 2 /* file copy, convert to lower case */
65 #define UCREBLOCK 3 /* file copy, convert to upper case */
66 #define NBASCII 4 /* file copy, convert from EBCDIC to ASCII */
67 #define LCNBASCII 5 /* file copy, EBCDIC to lower case ASCII */
68 #define UCNBASCII 6 /* file copy, EBCDIC to upper case ASCII */
69 #define NBEBCDIC 7 /* file copy, convert from ASCII to EBCDIC */
70 #define LCNBEBCDIC 8 /* file copy, ASCII to lower case EBCDIC */
71 #define UCNBEBCDIC 9 /* file copy, ASCII to upper case EBCDIC */
72 #define NBIBM 10 /* file copy, convert from ASCII to IBM */
73 #define LCNBIBM 11 /* file copy, ASCII to lower case IBM */
74 #define UCNBIBM 12 /* file copy, ASCII to upper case IBM */
75 #define UNBLOCK 13 /* convert blocked ASCII to ASCII */
76 #define LCUNBLOCK 14 /* convert blocked ASCII to lower case ASCII */
77 #define UCUNBLOCK 15 /* convert blocked ASCII to upper case ASCII */
78 #define ASCII 16 /* convert blocked EBCDIC to ASCII */
79 #define LCASCII 17 /* convert blocked EBCDIC to lower case ASCII */
80 #define UCASCII 18 /* convert blocked EBCDIC to upper case ASCII */
81 #define BLOCK 19 /* convert ASCII to blocked ASCII */
82 #define LCBLOCK 20 /* convert ASCII to lower case blocked ASCII */
83 #define UCBLOCK 21 /* convert ASCII to upper case blocked ASCII */
84 #define EBCDIC 22 /* convert ASCII to blocked EBCDIC */
85 #define LCEBCDIC 23 /* convert ASCII to lower case blocked EBCDIC */
86 #define UCEBCDIC 24 /* convert ASCII to upper case blocked EBCDIC */
87 #define IBM 25 /* convert ASCII to blocked IBM */
88 #define LCIBM 26 /* convert ASCII to lower case blocked IBM */
89 #define UCIBM 27 /* convert ASCII to upper case blocked IBM */
90 #define LCASE 01 /* flag - convert to lower case */
91 #define UCASE 02 /* flag - convert to upper case */
92 #define SWAB 04 /* flag - swap bytes before conversion */
93 #define NERR 010 /* flag - proceed on input errors */
94 #define SYNC 020 /* flag - pad short input blocks with nulls */
95 #define BADLIMIT 5 /* give up if no progress after BADLIMIT trys */
96 #define SVR4XLATE 0 /* use default EBCDIC translation */
97 #define BSDXLATE 1 /* use BSD-compatible EBCDIC translation */
99 #define USAGE\
100 "usage: dd [if=file] [of=file] [ibs=n|nk|nb|nxm] [obs=n|nk|nb|nxm]\n"\
101 " [bs=n|nk|nb|nxm] [cbs=n|nk|nb|nxm] [files=n] [skip=n]\n"\
102 " [iseek=n] [oseek=n] [seek=n] [count=n] [conv=[ascii]\n"\
103 " [,ebcdic][,ibm][,asciib][,ebcdicb][,ibmb]\n"\
104 " [,block|unblock][,lcase|ucase][,swab]\n"\
105 " [,noerror][,notrunc][,sync]]\n"
107 /* Global references */
109 /* Local routine declarations */
111 static int match(char *);
112 static void term();
113 static unsigned long long number();
114 static unsigned char *flsh();
115 static void stats();
117 /* Local data definitions */
119 static unsigned ibs; /* input buffer size */
120 static unsigned obs; /* output buffer size */
121 static unsigned bs; /* buffer size, overrules ibs and obs */
122 static unsigned cbs; /* conversion buffer size, used for block conversions */
123 static unsigned ibc; /* number of bytes still in the input buffer */
124 static unsigned obc; /* number of bytes in the output buffer */
125 static unsigned cbc; /* number of bytes in the conversion buffer */
127 static int ibf; /* input file descriptor */
128 static int obf; /* output file descriptor */
129 static int cflag; /* conversion option flags */
130 static int skipf; /* if skipf == 1, skip rest of input line */
131 static unsigned long long nifr; /* count of full input records */
132 static unsigned long long nipr; /* count of partial input records */
133 static unsigned long long nofr; /* count of full output records */
134 static unsigned long long nopr; /* count of partial output records */
135 static unsigned long long ntrunc; /* count of truncated input lines */
136 static unsigned long long nbad; /* count of bad records since last */
137 /* good one */
138 static int files; /* number of input files to concatenate (tape only) */
139 static off_t skip; /* number of input records to skip */
140 static off_t iseekn; /* number of input records to seek past */
141 static off_t oseekn; /* number of output records to seek past */
142 static unsigned long long count; /* number of input records to copy */
143 /* (0 = all) */
144 static int trantype; /* BSD or SVr4 compatible EBCDIC */
146 static char *string; /* command arg pointer */
147 static char *ifile; /* input file name pointer */
148 static char *ofile; /* output file name pointer */
149 static unsigned char *ibuf; /* input buffer pointer */
150 static unsigned char *obuf; /* output buffer pointer */
152 /* This is an EBCDIC to ASCII conversion table */
153 /* from a proposed BTL standard April 16, 1979 */
155 static unsigned char svr4_etoa [] =
157 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
158 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
159 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
160 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
161 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
162 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
163 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
164 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
165 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
166 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
167 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
168 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
169 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
170 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
171 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
172 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
173 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
174 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
175 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
176 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
177 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
178 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
179 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
180 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
181 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
182 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
183 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
184 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
185 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
186 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
187 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
188 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
191 /* This is an ASCII to EBCDIC conversion table */
192 /* from a proposed BTL standard April 16, 1979 */
194 static unsigned char svr4_atoe [] =
196 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
197 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
198 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
199 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
200 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
201 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
202 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
203 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
204 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
205 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
206 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
207 0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155,
208 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
209 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
210 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
211 0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007,
212 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
213 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
214 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
215 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
216 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
217 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
218 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
219 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
220 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
221 0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236,
222 0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257,
223 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
224 0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277,
225 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
226 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
227 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
230 /* Table for ASCII to IBM (alternate EBCDIC) code conversion */
232 static unsigned char svr4_atoibm[] =
234 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
235 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
236 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
237 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
238 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
239 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
240 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
241 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
242 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
243 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
244 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
245 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
246 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
247 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
248 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
249 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
250 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
251 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
252 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
253 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
254 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
255 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
256 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
257 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
258 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
259 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
260 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
261 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
262 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
263 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
264 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
265 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
268 /* Table for conversion of ASCII to lower case ASCII */
270 static unsigned char utol[] =
272 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
273 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
274 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
275 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
276 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
277 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
278 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
279 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
280 0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
281 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
282 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
283 0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
284 0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
285 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
286 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
287 0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
288 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
289 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
290 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
291 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
292 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
293 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
294 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
295 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
296 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
297 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
298 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
299 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
300 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
301 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
302 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
303 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
306 /* Table for conversion of ASCII to upper case ASCII */
308 static unsigned char ltou[] =
310 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
311 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
312 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
313 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
314 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
315 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
316 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
317 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
318 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
319 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
320 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
321 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
322 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
323 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
324 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
325 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
326 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
327 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
328 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
329 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
330 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
331 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
332 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
333 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
334 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
335 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
336 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
337 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
338 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
339 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
340 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
341 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
344 /* BSD-compatible EBCDIC to ASCII translate table */
346 static unsigned char bsd_etoa[] =
348 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
349 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
350 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
351 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
352 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
353 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
354 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
355 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
356 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
357 0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041,
358 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
359 0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136,
360 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
361 0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077,
362 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
363 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
364 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
365 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
366 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
367 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
368 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
369 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
370 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
371 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
372 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
373 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
374 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
375 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
376 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
377 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
378 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
379 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
382 /* BSD-compatible ASCII to EBCDIC translate table */
384 static unsigned char bsd_atoe[] =
386 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
387 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
388 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
389 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
390 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
391 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
392 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
393 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
394 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
395 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
396 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
397 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
398 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
399 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
400 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
401 0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007,
402 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
403 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
404 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
405 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
406 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
407 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
408 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
409 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
410 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
411 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
412 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
413 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
414 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
415 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
416 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
417 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
420 /* BSD-compatible ASCII to IBM translate table */
422 static unsigned char bsd_atoibm[] =
424 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
425 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
426 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
427 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
428 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
429 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
430 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
431 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
432 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
433 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
434 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
435 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
436 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
437 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
438 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
439 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
440 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
441 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
442 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
443 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
444 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
445 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
446 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
447 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
448 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
449 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
450 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
451 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
452 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
453 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
454 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
455 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
458 /* set up to use SVr4 ascii-ebcdic translation by default */
460 static unsigned char *atoe = svr4_atoe;
461 static unsigned char *etoa = svr4_etoa;
462 static unsigned char *atoibm = svr4_atoibm;
466 main(int argc, char **argv)
468 unsigned char *ip, *op; /* input and output buffer pointers */
469 int c; /* character counter */
470 int ic; /* input character */
471 int conv; /* conversion option code */
472 int trunc; /* whether output file is truncated */
473 struct stat file_stat;
475 /* Set option defaults */
477 ibs = BSIZE;
478 obs = BSIZE;
479 files = 1;
480 conv = COPY;
481 trunc = 1; /* default: truncate output file */
482 trantype = SVR4XLATE; /* use SVR4 EBCDIC by default */
484 /* Parse command options */
486 (void) setlocale(LC_ALL, "");
487 #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
488 #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
489 #endif
490 (void) textdomain(TEXT_DOMAIN);
492 while ((c = getopt(argc, argv, "")) != EOF)
493 switch (c) {
494 case '?':
495 (void) fprintf(stderr, USAGE);
496 exit(2);
499 /* not getopt()'ed because dd has no options but only operand(s) */
501 for (c = optind; c < argc; c++)
503 string = argv[c];
504 if (match("ibs="))
506 ibs = (unsigned)number(BIG);
507 continue;
509 if (match("obs="))
511 obs = (unsigned)number(BIG);
512 continue;
514 if (match("cbs="))
516 cbs = (unsigned)number(BIG);
517 continue;
519 if (match("bs="))
521 bs = (unsigned)number(BIG);
522 continue;
524 if (match("if="))
526 ifile = string;
527 continue;
529 if (match("of="))
531 ofile = string;
532 continue;
534 if (match("skip="))
536 skip = number(BIG);
537 continue;
539 if (match("iseek="))
541 iseekn = number(BIG);
542 continue;
544 if (match("oseek="))
546 oseekn = number(BIG);
547 continue;
549 if (match("seek=")) /* retained for compatibility */
551 oseekn = number(BIG);
552 continue;
554 if (match("count="))
556 count = number(BIG);
557 continue;
559 if (match("files="))
561 files = (int)number(BIG);
562 continue;
564 if (match("conv="))
566 for (;;)
568 if (match(","))
570 continue;
572 if (*string == '\0')
574 break;
576 if (match("block"))
578 conv = BLOCK;
579 continue;
581 if (match("unblock"))
583 conv = UNBLOCK;
584 continue;
587 /* ebcdicb, ibmb, and asciib must precede */
588 /* ebcdic, ibm, and ascii in this test */
590 if (match("ebcdicb"))
592 conv = EBCDIC;
593 trantype = BSDXLATE;
594 continue;
596 if (match("ibmb"))
598 conv = IBM;
599 trantype = BSDXLATE;
600 continue;
602 if (match("asciib"))
604 conv = ASCII;
605 trantype = BSDXLATE;
606 continue;
608 if (match("ebcdic"))
610 conv = EBCDIC;
611 trantype = SVR4XLATE;
612 continue;
614 if (match("ibm"))
616 conv = IBM;
617 trantype = SVR4XLATE;
618 continue;
620 if (match("ascii"))
622 conv = ASCII;
623 trantype = SVR4XLATE;
624 continue;
626 if (match("lcase"))
628 cflag |= LCASE;
629 continue;
631 if (match("ucase"))
633 cflag |= UCASE;
634 continue;
636 if (match("swab"))
638 cflag |= SWAB;
639 continue;
641 if (match("noerror"))
643 cflag |= NERR;
644 continue;
646 if (match("notrunc"))
648 trunc = 0;
649 continue;
651 if (match("sync"))
653 cflag |= SYNC;
654 continue;
656 goto badarg;
658 continue;
660 badarg:
661 (void) fprintf(stderr, "dd: %s \"%s\"\n",
662 gettext("bad argument:"), string);
663 exit(2);
666 /* Perform consistency checks on options, decode strange conventions */
668 if (bs)
670 ibs = obs = bs;
672 if ((ibs == 0) || (obs == 0))
674 (void) fprintf(stderr, "dd: %s\n",
675 gettext("buffer sizes cannot be zero"));
676 exit(2);
678 if (conv == COPY)
680 if ((bs == 0) || (cflag&(LCASE|UCASE)))
682 conv = REBLOCK;
685 if (cbs == 0)
687 switch (conv)
689 case BLOCK:
690 case UNBLOCK:
691 conv = REBLOCK;
692 break;
694 case ASCII:
695 conv = NBASCII;
696 break;
698 case EBCDIC:
699 conv = NBEBCDIC;
700 break;
702 case IBM:
703 conv = NBIBM;
704 break;
708 /* Expand options into lower and upper case versions if necessary */
710 switch (conv)
712 case REBLOCK:
713 if (cflag&LCASE)
714 conv = LCREBLOCK;
715 else if (cflag&UCASE)
716 conv = UCREBLOCK;
717 break;
719 case UNBLOCK:
720 if (cflag&LCASE)
721 conv = LCUNBLOCK;
722 else if (cflag&UCASE)
723 conv = UCUNBLOCK;
724 break;
726 case BLOCK:
727 if (cflag&LCASE)
728 conv = LCBLOCK;
729 else if (cflag&UCASE)
730 conv = UCBLOCK;
731 break;
733 case ASCII:
734 if (cflag&LCASE)
735 conv = LCASCII;
736 else if (cflag&UCASE)
737 conv = UCASCII;
738 break;
740 case NBASCII:
741 if (cflag&LCASE)
742 conv = LCNBASCII;
743 else if (cflag&UCASE)
744 conv = UCNBASCII;
745 break;
747 case EBCDIC:
748 if (cflag&LCASE)
749 conv = LCEBCDIC;
750 else if (cflag&UCASE)
751 conv = UCEBCDIC;
752 break;
754 case NBEBCDIC:
755 if (cflag&LCASE)
756 conv = LCNBEBCDIC;
757 else if (cflag&UCASE)
758 conv = UCNBEBCDIC;
759 break;
761 case IBM:
762 if (cflag&LCASE)
763 conv = LCIBM;
764 else if (cflag&UCASE)
765 conv = UCIBM;
766 break;
768 case NBIBM:
769 if (cflag&LCASE)
770 conv = LCNBIBM;
771 else if (cflag&UCASE)
772 conv = UCNBIBM;
773 break;
776 /* If BSD-compatible translation is selected, change the tables */
778 if (trantype == BSDXLATE) {
779 atoe = bsd_atoe;
780 atoibm = bsd_atoibm;
781 etoa = bsd_etoa;
783 /* Open the input file, or duplicate standard input */
785 ibf = -1;
786 if (ifile)
788 ibf = open(ifile, 0);
790 #ifndef STANDALONE
791 else
793 ifile = "";
794 ibf = dup(0);
796 #endif
797 if (ibf == -1)
799 (void) fprintf(stderr, "dd: %s: ", ifile);
800 perror("open");
801 exit(2);
804 /* Open the output file, or duplicate standard output */
806 obf = -1;
807 if (ofile)
809 if (trunc == 0) /* do not truncate output file */
810 obf = open(ofile, (O_WRONLY|O_CREAT),
811 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
812 else if (oseekn && (trunc == 1))
814 obf = open(ofile, O_WRONLY|O_CREAT,
815 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
816 if (obf == -1)
818 (void) fprintf(stderr, "dd: %s: ", ofile);
819 perror("open");
820 exit(2);
822 (void) fstat(obf, &file_stat);
823 if (((file_stat.st_mode & S_IFMT) == S_IFREG) &&
824 (ftruncate(obf, (((off_t)oseekn) * ((off_t)obs)))
825 == -1))
827 perror("ftruncate");
828 exit(2);
831 else
832 obf = creat(ofile,
833 (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
835 #ifndef STANDALONE
836 else
838 ofile = "";
839 obf = dup(1);
841 #endif
842 if (obf == -1)
844 (void) fprintf(stderr, "dd: %s: ", ofile);
845 perror("open");
846 exit(2);
849 /* Expand memory to get an input buffer */
851 ibuf = (unsigned char *)valloc(ibs + 10);
853 /* If no conversions, the input buffer is the output buffer */
855 if (conv == COPY)
857 obuf = ibuf;
860 /* Expand memory to get an output buffer. Leave enough room at the */
861 /* end to convert a logical record when doing block conversions. */
863 else
865 obuf = (unsigned char *)valloc(obs + cbs + 10);
867 if ((ibuf == (unsigned char *)NULL) || (obuf == (unsigned char *)NULL))
869 (void) fprintf(stderr,
870 "dd: %s\n", gettext("not enough memory"));
871 exit(2);
874 /* Enable a statistics message on SIGINT */
876 #ifndef STANDALONE
877 if (signal(SIGINT, SIG_IGN) != SIG_IGN)
879 (void) signal(SIGINT, term);
881 #endif
882 /* Skip input blocks */
884 while (skip)
886 ibc = read(ibf, (char *)ibuf, ibs);
887 if (ibc == (unsigned)-1)
889 if (++nbad > BADLIMIT)
891 (void) fprintf(stderr, "dd: %s\n",
892 gettext("skip failed"));
893 exit(2);
895 else
897 perror("read");
900 else
902 if (ibc == 0)
904 (void) fprintf(stderr, "dd: %s\n",
905 gettext("cannot skip past end-of-file"));
906 exit(3);
908 else
910 nbad = 0;
913 skip--;
916 /* Seek past input blocks */
918 if (iseekn && lseek(ibf, (((off_t)iseekn) * ((off_t)ibs)), 1) == -1)
920 perror("lseek");
921 exit(2);
924 /* Seek past output blocks */
926 if (oseekn && lseek(obf, (((off_t)oseekn) * ((off_t)obs)), 1) == -1)
928 perror("lseek");
929 exit(2);
932 /* Initialize all buffer pointers */
934 skipf = 0; /* not skipping an input line */
935 ibc = 0; /* no input characters yet */
936 obc = 0; /* no output characters yet */
937 cbc = 0; /* the conversion buffer is empty */
938 op = obuf; /* point to the output buffer */
940 /* Read and convert input blocks until end of file(s) */
942 for (;;)
944 if ((count == 0) || (nifr+nipr < count))
946 /* If proceed on error is enabled, zero the input buffer */
948 if (cflag&NERR)
950 ip = ibuf + ibs;
951 c = ibs;
952 if (c & 1) /* if the size is odd, */
954 *--ip = 0; /* clear the odd byte */
956 if (c >>= 1) /* divide by two */
958 do { /* clear two at a time */
959 *--ip = 0;
960 *--ip = 0;
961 } while (--c);
965 /* Read the next input block */
967 ibc = read(ibf, (char *)ibuf, ibs);
969 /* Process input errors */
971 if (ibc == (unsigned)-1)
973 perror("read");
974 if (((cflag&NERR) == 0) || (++nbad > BADLIMIT))
976 while (obc)
978 (void) flsh();
980 term(2);
982 else
984 stats();
985 ibc = ibs; /* assume a full block */
988 else
990 nbad = 0;
994 /* Record count satisfied, simulate end of file */
996 else
998 ibc = 0;
999 files = 1;
1002 /* Process end of file */
1004 if (ibc == 0)
1006 switch (conv)
1008 case UNBLOCK:
1009 case LCUNBLOCK:
1010 case UCUNBLOCK:
1011 case ASCII:
1012 case LCASCII:
1013 case UCASCII:
1015 /* Trim trailing blanks from the last line */
1017 if ((c = cbc) != 0)
1019 do {
1020 if ((*--op) != ' ')
1022 op++;
1023 break;
1025 } while (--c);
1026 *op++ = '\n';
1027 obc -= cbc - c - 1;
1028 cbc = 0;
1030 /* Flush the output buffer if full */
1032 while (obc >= obs)
1034 op = flsh();
1037 break;
1039 case BLOCK:
1040 case LCBLOCK:
1041 case UCBLOCK:
1042 case EBCDIC:
1043 case LCEBCDIC:
1044 case UCEBCDIC:
1045 case IBM:
1046 case LCIBM:
1047 case UCIBM:
1049 /* Pad trailing blanks if the last line is short */
1051 if (cbc)
1053 obc += c = cbs - cbc;
1054 cbc = 0;
1055 if (c > 0)
1057 /* Use the right kind of blank */
1059 switch (conv)
1061 case BLOCK:
1062 case LCBLOCK:
1063 case UCBLOCK:
1064 ic = ' ';
1065 break;
1067 case EBCDIC:
1068 case LCEBCDIC:
1069 case UCEBCDIC:
1070 ic = atoe[' '];
1071 break;
1073 case IBM:
1074 case LCIBM:
1075 case UCIBM:
1076 ic = atoibm[' '];
1077 break;
1080 /* Pad with trailing blanks */
1082 do {
1083 *op++ = ic;
1084 } while (--c);
1089 /* Flush the output buffer if full */
1091 while (obc >= obs)
1093 op = flsh();
1095 break;
1098 /* If no more files to read, flush the output buffer */
1100 if (--files <= 0)
1102 (void) flsh();
1103 if ((close(obf) != 0) || (fclose(stdout) != 0))
1105 perror(gettext("dd: close error"));
1106 exit(2);
1108 term(0); /* successful exit */
1110 else
1112 continue; /* read the next file */
1116 /* Normal read, check for special cases */
1118 else if (ibc == ibs)
1120 nifr++; /* count another full input record */
1122 else
1124 nipr++; /* count a partial input record */
1126 /* If `sync' enabled, pad nulls */
1128 if ((cflag&SYNC) && ((cflag&NERR) == 0))
1130 c = ibs - ibc;
1131 ip = ibuf + ibs;
1132 do {
1133 if ((conv == BLOCK) || (conv == UNBLOCK))
1134 *--ip = ' ';
1135 else
1136 *--ip = '\0';
1137 } while (--c);
1138 ibc = ibs;
1142 /* Swap the bytes in the input buffer if necessary */
1144 if (cflag&SWAB)
1146 ip = ibuf;
1147 if (ibc & 1) /* if the byte count is odd, */
1149 ip[ibc] = 0; /* make it even, pad with zero */
1151 c = ibc >> 1; /* compute the pair count */
1152 do {
1153 ic = *ip++;
1154 ip[-1] = *ip;
1155 *ip++ = ic;
1156 } while (--c); /* do two bytes at a time */
1159 /* Select the appropriate conversion loop */
1161 ip = ibuf;
1162 switch (conv)
1165 /* Simple copy: no conversion, preserve the input block size */
1167 case COPY:
1168 obc = ibc;
1169 (void) flsh();
1170 break;
1172 /* Simple copy: pack all output into equal sized blocks */
1174 case REBLOCK:
1175 case LCREBLOCK:
1176 case UCREBLOCK:
1177 case NBASCII:
1178 case LCNBASCII:
1179 case UCNBASCII:
1180 case NBEBCDIC:
1181 case LCNBEBCDIC:
1182 case UCNBEBCDIC:
1183 case NBIBM:
1184 case LCNBIBM:
1185 case UCNBIBM:
1186 while ((c = ibc) != 0)
1188 if (c > (obs - obc))
1190 c = obs - obc;
1192 ibc -= c;
1193 obc += c;
1194 switch (conv)
1196 case REBLOCK:
1197 do {
1198 *op++ = *ip++;
1199 } while (--c);
1200 break;
1202 case LCREBLOCK:
1203 do {
1204 *op++ = utol[*ip++];
1205 } while (--c);
1206 break;
1208 case UCREBLOCK:
1209 do {
1210 *op++ = ltou[*ip++];
1211 } while (--c);
1212 break;
1214 case NBASCII:
1215 do {
1216 *op++ = etoa[*ip++];
1217 } while (--c);
1218 break;
1220 case LCNBASCII:
1221 do {
1222 *op++ = utol[etoa[*ip++]];
1223 } while (--c);
1224 break;
1226 case UCNBASCII:
1227 do {
1228 *op++ = ltou[etoa[*ip++]];
1229 } while (--c);
1230 break;
1232 case NBEBCDIC:
1233 do {
1234 *op++ = atoe[*ip++];
1235 } while (--c);
1236 break;
1238 case LCNBEBCDIC:
1239 do {
1240 *op++ = atoe[utol[*ip++]];
1241 } while (--c);
1242 break;
1244 case UCNBEBCDIC:
1245 do {
1246 *op++ = atoe[ltou[*ip++]];
1247 } while (--c);
1248 break;
1250 case NBIBM:
1251 do {
1252 *op++ = atoibm[*ip++];
1253 } while (--c);
1254 break;
1256 case LCNBIBM:
1257 do {
1258 *op++ = atoibm[utol[*ip++]];
1259 } while (--c);
1260 break;
1262 case UCNBIBM:
1263 do {
1264 *op++ = atoibm[ltou[*ip++]];
1265 } while (--c);
1266 break;
1268 if (obc >= obs)
1270 op = flsh();
1273 break;
1275 /* Convert from blocked records to lines terminated by newline */
1277 case UNBLOCK:
1278 case LCUNBLOCK:
1279 case UCUNBLOCK:
1280 case ASCII:
1281 case LCASCII:
1282 case UCASCII:
1283 while ((c = ibc) != 0)
1285 if (c > (cbs - cbc))
1286 /* if more than one record, */
1288 c = cbs - cbc;
1289 /* only copy one record */
1291 ibc -= c;
1292 cbc += c;
1293 obc += c;
1294 switch (conv)
1296 case UNBLOCK:
1297 do {
1298 *op++ = *ip++;
1299 } while (--c);
1300 break;
1302 case LCUNBLOCK:
1303 do {
1304 *op++ = utol[*ip++];
1305 } while (--c);
1306 break;
1308 case UCUNBLOCK:
1309 do {
1310 *op++ = ltou[*ip++];
1311 } while (--c);
1312 break;
1314 case ASCII:
1315 do {
1316 *op++ = etoa[*ip++];
1317 } while (--c);
1318 break;
1320 case LCASCII:
1321 do {
1322 *op++ = utol[etoa[*ip++]];
1323 } while (--c);
1324 break;
1326 case UCASCII:
1327 do {
1328 *op++ = ltou[etoa[*ip++]];
1329 } while (--c);
1330 break;
1333 /* Trim trailing blanks if the line is full */
1335 if (cbc == cbs)
1337 c = cbs; /* `do - while' is usually */
1338 do { /* faster than `for' */
1339 if ((*--op) != ' ')
1341 op++;
1342 break;
1344 } while (--c);
1345 *op++ = '\n';
1346 obc -= cbs - c - 1;
1347 cbc = 0;
1349 /* Flush the output buffer if full */
1351 while (obc >= obs)
1353 op = flsh();
1357 break;
1359 /* Convert to blocked records */
1361 case BLOCK:
1362 case LCBLOCK:
1363 case UCBLOCK:
1364 case EBCDIC:
1365 case LCEBCDIC:
1366 case UCEBCDIC:
1367 case IBM:
1368 case LCIBM:
1369 case UCIBM:
1370 while ((c = ibc) != 0)
1372 int nlflag = 0;
1374 /* We may have to skip to the end of a long line */
1376 if (skipf)
1378 do {
1379 if ((ic = *ip++) == '\n')
1381 skipf = 0;
1382 c--;
1383 break;
1385 } while (--c);
1386 if ((ibc = c) == 0)
1388 continue;
1389 /* read another block */
1393 /* If anything left, copy until newline */
1395 if (c > (cbs - cbc + 1))
1397 c = cbs - cbc + 1;
1399 ibc -= c;
1400 cbc += c;
1401 obc += c;
1403 switch (conv)
1405 case BLOCK:
1406 do {
1407 if ((ic = *ip++) != '\n')
1409 *op++ = ic;
1411 else
1413 nlflag = 1;
1414 break;
1416 } while (--c);
1417 break;
1419 case LCBLOCK:
1420 do {
1421 if ((ic = *ip++) != '\n')
1423 *op++ = utol[ic];
1425 else
1427 nlflag = 1;
1428 break;
1430 } while (--c);
1431 break;
1433 case UCBLOCK:
1434 do {
1435 if ((ic = *ip++) != '\n')
1437 *op++ = ltou[ic];
1439 else
1441 nlflag = 1;
1442 break;
1444 } while (--c);
1445 break;
1447 case EBCDIC:
1448 do {
1449 if ((ic = *ip++) != '\n')
1451 *op++ = atoe[ic];
1453 else
1455 nlflag = 1;
1456 break;
1458 } while (--c);
1459 break;
1461 case LCEBCDIC:
1462 do {
1463 if ((ic = *ip++) != '\n')
1465 *op++ = atoe[utol[ic]];
1467 else
1469 nlflag = 1;
1470 break;
1472 } while (--c);
1473 break;
1475 case UCEBCDIC:
1476 do {
1477 if ((ic = *ip++) != '\n')
1479 *op++ = atoe[ltou[ic]];
1481 else
1483 nlflag = 1;
1484 break;
1486 } while (--c);
1487 break;
1489 case IBM:
1490 do {
1491 if ((ic = *ip++) != '\n')
1493 *op++ = atoibm[ic];
1495 else
1497 nlflag = 1;
1498 break;
1500 } while (--c);
1501 break;
1503 case LCIBM:
1504 do {
1505 if ((ic = *ip++) != '\n')
1507 *op++ = atoibm[utol[ic]];
1509 else
1511 nlflag = 1;
1512 break;
1514 } while (--c);
1515 break;
1517 case UCIBM:
1518 do {
1519 if ((ic = *ip++) != '\n')
1521 *op++ = atoibm[ltou[ic]];
1523 else
1525 nlflag = 1;
1526 break;
1528 } while (--c);
1529 break;
1532 /* If newline found, update all the counters and */
1533 /* pointers, pad with trailing blanks if necessary */
1535 if (nlflag)
1537 ibc += c - 1;
1538 obc += cbs - cbc;
1539 c += cbs - cbc;
1540 cbc = 0;
1541 if (c > 0)
1543 /* Use the right kind of blank */
1545 switch (conv)
1547 case BLOCK:
1548 case LCBLOCK:
1549 case UCBLOCK:
1550 ic = ' ';
1551 break;
1553 case EBCDIC:
1554 case LCEBCDIC:
1555 case UCEBCDIC:
1556 ic = atoe[' '];
1557 break;
1559 case IBM:
1560 case LCIBM:
1561 case UCIBM:
1562 ic = atoibm[' '];
1563 break;
1566 /* Pad with trailing blanks */
1568 do {
1569 *op++ = ic;
1570 } while (--c);
1574 /* If not end of line, this line may be too long */
1576 else if (cbc > cbs)
1578 skipf = 1; /* note skip in progress */
1579 obc--;
1580 op--;
1581 cbc = 0;
1582 ntrunc++; /* count another long line */
1585 /* Flush the output buffer if full */
1587 while (obc >= obs)
1589 op = flsh();
1592 break;
1595 /* NOTREACHED */
1596 return (0);
1599 /* match ************************************************************** */
1600 /* */
1601 /* Compare two text strings for equality */
1602 /* */
1603 /* Arg: s - pointer to string to match with a command arg */
1604 /* Global arg: string - pointer to command arg */
1605 /* */
1606 /* Return: 1 if match, 0 if no match */
1607 /* If match, also reset `string' to point to the text */
1608 /* that follows the matching text. */
1609 /* */
1610 /* ******************************************************************** */
1612 static int
1613 match(s)
1614 char *s;
1616 char *cs;
1618 cs = string;
1619 while (*cs++ == *s)
1621 if (*s++ == '\0')
1623 goto true;
1626 if (*s != '\0')
1628 return (0);
1631 true:
1632 cs--;
1633 string = cs;
1634 return (1);
1637 /* number ************************************************************* */
1638 /* */
1639 /* Convert a numeric arg to binary */
1640 /* */
1641 /* Arg: big - maximum valid input number */
1642 /* Global arg: string - pointer to command arg */
1643 /* */
1644 /* Valid forms: 123 | 123k | 123M | 123G | 123T | 123P | 123E | 123Z | */
1645 /* 123w | 123b | 123*123 | 123x123 */
1646 /* plus combinations such as 2b*3kw*4w */
1647 /* */
1648 /* Return: converted number */
1649 /* */
1650 /* ******************************************************************** */
1652 static unsigned long long
1653 number(big)
1654 long long big;
1656 char *cs;
1657 long long n;
1658 long long cut = BIG / 10; /* limit to avoid overflow */
1660 cs = string;
1661 n = 0;
1662 while ((*cs >= '0') && (*cs <= '9') && (n <= cut))
1664 n = n*10 + *cs++ - '0';
1666 for (;;)
1668 switch (*cs++)
1671 case 'Z':
1672 n *= 1024;
1673 /* FALLTHROUGH */
1675 case 'E':
1676 n *= 1024;
1677 /* FALLTHROUGH */
1679 case 'P':
1680 n *= 1024;
1681 /* FALLTHROUGH */
1683 case 'T':
1684 n *= 1024;
1685 /* FALLTHROUGH */
1687 case 'G':
1688 n *= 1024;
1689 /* FALLTHROUGH */
1691 case 'M':
1692 n *= 1024;
1693 /* FALLTHROUGH */
1695 case 'k':
1696 n *= 1024;
1697 continue;
1699 case 'w':
1700 n *= 2;
1701 continue;
1703 case 'b':
1704 n *= BSIZE;
1705 continue;
1707 case '*':
1708 case 'x':
1709 string = cs;
1710 n *= number(BIG);
1712 /* FALLTHROUGH */
1713 /* Fall into exit test, recursion has read rest of string */
1714 /* End of string, check for a valid number */
1716 case '\0':
1717 if ((n > big) || (n < 0))
1719 (void) fprintf(stderr, "dd: %s \"%llu\"\n",
1720 gettext("argument out of range:"), n);
1721 exit(2);
1723 return (n);
1725 default:
1726 (void) fprintf(stderr, "dd: %s \"%s\"\n",
1727 gettext("bad numeric argument:"), string);
1728 exit(2);
1730 } /* never gets here */
1733 /* flsh *************************************************************** */
1734 /* */
1735 /* Flush the output buffer, move any excess bytes down to the beginning */
1736 /* */
1737 /* Arg: none */
1738 /* Global args: obuf, obc, obs, nofr, nopr */
1739 /* */
1740 /* Return: Pointer to the first free byte in the output buffer. */
1741 /* Also reset `obc' to account for moved bytes. */
1742 /* */
1743 /* ******************************************************************** */
1745 static unsigned char
1746 *flsh()
1748 unsigned char *op, *cp;
1749 int bc;
1750 unsigned int oc;
1752 if (obc) /* don't flush if the buffer is empty */
1754 if (obc >= obs) {
1755 oc = obs;
1756 nofr++; /* count a full output buffer */
1758 else
1760 oc = obc;
1761 nopr++; /* count a partial output buffer */
1763 bc = write(obf, (char *)obuf, oc);
1764 if (bc != oc) {
1765 if (bc < 0)
1766 perror("write");
1767 else
1768 (void) fprintf(stderr,
1769 gettext("dd: unexpected short write, "
1770 "wrote %d bytes, expected %d\n"), bc, oc);
1771 term(2);
1773 obc -= oc;
1774 op = obuf;
1776 /* If any data in the conversion buffer, move it into */
1777 /* the output buffer */
1779 if (obc) {
1780 cp = obuf + obs;
1781 bc = obc;
1782 do {
1783 *op++ = *cp++;
1784 } while (--bc);
1786 return (op);
1788 return (obuf);
1791 /* term *************************************************************** */
1792 /* */
1793 /* Write record statistics, then exit */
1794 /* */
1795 /* Arg: c - exit status code */
1796 /* */
1797 /* Return: no return, calls exit */
1798 /* */
1799 /* ******************************************************************** */
1801 static void
1802 term(c)
1803 int c;
1805 stats();
1806 exit(c);
1809 /* stats ************************************************************** */
1810 /* */
1811 /* Write record statistics onto standard error */
1812 /* */
1813 /* Args: none */
1814 /* Global args: nifr, nipr, nofr, nopr, ntrunc */
1815 /* */
1816 /* Return: void */
1817 /* */
1818 /* ******************************************************************** */
1820 static void
1821 stats()
1823 (void) fprintf(stderr, gettext("%llu+%llu records in\n"), nifr, nipr);
1824 (void) fprintf(stderr, gettext("%llu+%llu records out\n"), nofr, nopr);
1825 if (ntrunc) {
1826 (void) fprintf(stderr,
1827 gettext("%llu truncated record(s)\n"), ntrunc);