10Sstevel@tonic-gate /*
20Sstevel@tonic-gate * CDDL HEADER START
30Sstevel@tonic-gate *
40Sstevel@tonic-gate * The contents of this file are subject to the terms of the
50Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
60Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
70Sstevel@tonic-gate * with the License.
80Sstevel@tonic-gate *
90Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
100Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
110Sstevel@tonic-gate * See the License for the specific language governing permissions
120Sstevel@tonic-gate * and limitations under the License.
130Sstevel@tonic-gate *
140Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
150Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
160Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
170Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
180Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
190Sstevel@tonic-gate *
200Sstevel@tonic-gate * CDDL HEADER END
210Sstevel@tonic-gate */
22*212Scf46844
23*212Scf46844 /*
24*212Scf46844 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
25*212Scf46844 * Use is subject to license terms.
26*212Scf46844 */
27*212Scf46844
280Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
290Sstevel@tonic-gate /* All Rights Reserved */
300Sstevel@tonic-gate
310Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
320Sstevel@tonic-gate
330Sstevel@tonic-gate /*
340Sstevel@tonic-gate * convert and copy
350Sstevel@tonic-gate */
360Sstevel@tonic-gate
370Sstevel@tonic-gate #include <stdio.h>
380Sstevel@tonic-gate #include <signal.h>
390Sstevel@tonic-gate #include <fcntl.h>
400Sstevel@tonic-gate #include <sys/param.h>
410Sstevel@tonic-gate #include <sys/types.h>
420Sstevel@tonic-gate #include <sys/sysmacros.h>
430Sstevel@tonic-gate #include <sys/stat.h>
440Sstevel@tonic-gate #include <unistd.h>
450Sstevel@tonic-gate #include <stdlib.h>
460Sstevel@tonic-gate #include <locale.h>
470Sstevel@tonic-gate #include <string.h>
480Sstevel@tonic-gate
490Sstevel@tonic-gate /* The BIG parameter is machine dependent. It should be a long integer */
500Sstevel@tonic-gate /* constant that can be used by the number parser to check the validity */
510Sstevel@tonic-gate /* of numeric parameters. On 16-bit machines, it should probably be */
520Sstevel@tonic-gate /* the maximum unsigned integer, 0177777L. On 32-bit machines where */
530Sstevel@tonic-gate /* longs are the same size as ints, the maximum signed integer is more */
540Sstevel@tonic-gate /* appropriate. This value is 017777777777L. In 64 bit environments, */
550Sstevel@tonic-gate /* the maximum signed integer value is 0777777777777777777777LL */
560Sstevel@tonic-gate
570Sstevel@tonic-gate #define BIG 0777777777777777777777LL
580Sstevel@tonic-gate
590Sstevel@tonic-gate #define BSIZE 512
600Sstevel@tonic-gate
610Sstevel@tonic-gate /* Option parameters */
620Sstevel@tonic-gate
630Sstevel@tonic-gate #define COPY 0 /* file copy, preserve input block size */
640Sstevel@tonic-gate #define REBLOCK 1 /* file copy, change block size */
650Sstevel@tonic-gate #define LCREBLOCK 2 /* file copy, convert to lower case */
660Sstevel@tonic-gate #define UCREBLOCK 3 /* file copy, convert to upper case */
670Sstevel@tonic-gate #define NBASCII 4 /* file copy, convert from EBCDIC to ASCII */
680Sstevel@tonic-gate #define LCNBASCII 5 /* file copy, EBCDIC to lower case ASCII */
690Sstevel@tonic-gate #define UCNBASCII 6 /* file copy, EBCDIC to upper case ASCII */
700Sstevel@tonic-gate #define NBEBCDIC 7 /* file copy, convert from ASCII to EBCDIC */
710Sstevel@tonic-gate #define LCNBEBCDIC 8 /* file copy, ASCII to lower case EBCDIC */
720Sstevel@tonic-gate #define UCNBEBCDIC 9 /* file copy, ASCII to upper case EBCDIC */
730Sstevel@tonic-gate #define NBIBM 10 /* file copy, convert from ASCII to IBM */
740Sstevel@tonic-gate #define LCNBIBM 11 /* file copy, ASCII to lower case IBM */
750Sstevel@tonic-gate #define UCNBIBM 12 /* file copy, ASCII to upper case IBM */
760Sstevel@tonic-gate #define UNBLOCK 13 /* convert blocked ASCII to ASCII */
770Sstevel@tonic-gate #define LCUNBLOCK 14 /* convert blocked ASCII to lower case ASCII */
780Sstevel@tonic-gate #define UCUNBLOCK 15 /* convert blocked ASCII to upper case ASCII */
790Sstevel@tonic-gate #define ASCII 16 /* convert blocked EBCDIC to ASCII */
800Sstevel@tonic-gate #define LCASCII 17 /* convert blocked EBCDIC to lower case ASCII */
810Sstevel@tonic-gate #define UCASCII 18 /* convert blocked EBCDIC to upper case ASCII */
820Sstevel@tonic-gate #define BLOCK 19 /* convert ASCII to blocked ASCII */
830Sstevel@tonic-gate #define LCBLOCK 20 /* convert ASCII to lower case blocked ASCII */
840Sstevel@tonic-gate #define UCBLOCK 21 /* convert ASCII to upper case blocked ASCII */
850Sstevel@tonic-gate #define EBCDIC 22 /* convert ASCII to blocked EBCDIC */
860Sstevel@tonic-gate #define LCEBCDIC 23 /* convert ASCII to lower case blocked EBCDIC */
870Sstevel@tonic-gate #define UCEBCDIC 24 /* convert ASCII to upper case blocked EBCDIC */
880Sstevel@tonic-gate #define IBM 25 /* convert ASCII to blocked IBM */
890Sstevel@tonic-gate #define LCIBM 26 /* convert ASCII to lower case blocked IBM */
900Sstevel@tonic-gate #define UCIBM 27 /* convert ASCII to upper case blocked IBM */
910Sstevel@tonic-gate #define LCASE 01 /* flag - convert to lower case */
920Sstevel@tonic-gate #define UCASE 02 /* flag - convert to upper case */
930Sstevel@tonic-gate #define SWAB 04 /* flag - swap bytes before conversion */
940Sstevel@tonic-gate #define NERR 010 /* flag - proceed on input errors */
950Sstevel@tonic-gate #define SYNC 020 /* flag - pad short input blocks with nulls */
960Sstevel@tonic-gate #define BADLIMIT 5 /* give up if no progress after BADLIMIT trys */
970Sstevel@tonic-gate #define SVR4XLATE 0 /* use default EBCDIC translation */
980Sstevel@tonic-gate #define BSDXLATE 1 /* use BSD-compatible EBCDIC translation */
990Sstevel@tonic-gate
1000Sstevel@tonic-gate #define USAGE\
1010Sstevel@tonic-gate "usage: dd [if=file] [of=file] [ibs=n|nk|nb|nxm] [obs=n|nk|nb|nxm]\n"\
1020Sstevel@tonic-gate " [bs=n|nk|nb|nxm] [cbs=n|nk|nb|nxm] [files=n] [skip=n]\n"\
1030Sstevel@tonic-gate " [iseek=n] [oseek=n] [seek=n] [count=n] [conv=[ascii]\n"\
1040Sstevel@tonic-gate " [,ebcdic][,ibm][,asciib][,ebcdicb][,ibmb]\n"\
1050Sstevel@tonic-gate " [,block|unblock][,lcase|ucase][,swab]\n"\
1060Sstevel@tonic-gate " [,noerror][,notrunc][,sync]]\n"
1070Sstevel@tonic-gate
1080Sstevel@tonic-gate /* Global references */
1090Sstevel@tonic-gate
1100Sstevel@tonic-gate /* Local routine declarations */
1110Sstevel@tonic-gate
1120Sstevel@tonic-gate static int match(char *);
1130Sstevel@tonic-gate static void term();
1140Sstevel@tonic-gate static unsigned long long number();
1150Sstevel@tonic-gate static unsigned char *flsh();
1160Sstevel@tonic-gate static void stats();
1170Sstevel@tonic-gate
1180Sstevel@tonic-gate /* Local data definitions */
1190Sstevel@tonic-gate
1200Sstevel@tonic-gate static unsigned ibs; /* input buffer size */
1210Sstevel@tonic-gate static unsigned obs; /* output buffer size */
1220Sstevel@tonic-gate static unsigned bs; /* buffer size, overrules ibs and obs */
1230Sstevel@tonic-gate static unsigned cbs; /* conversion buffer size, used for block conversions */
1240Sstevel@tonic-gate static unsigned ibc; /* number of bytes still in the input buffer */
1250Sstevel@tonic-gate static unsigned obc; /* number of bytes in the output buffer */
1260Sstevel@tonic-gate static unsigned cbc; /* number of bytes in the conversion buffer */
1270Sstevel@tonic-gate
1280Sstevel@tonic-gate static int ibf; /* input file descriptor */
1290Sstevel@tonic-gate static int obf; /* output file descriptor */
1300Sstevel@tonic-gate static int cflag; /* conversion option flags */
1310Sstevel@tonic-gate static int skipf; /* if skipf == 1, skip rest of input line */
1320Sstevel@tonic-gate static unsigned long long nifr; /* count of full input records */
1330Sstevel@tonic-gate static unsigned long long nipr; /* count of partial input records */
1340Sstevel@tonic-gate static unsigned long long nofr; /* count of full output records */
1350Sstevel@tonic-gate static unsigned long long nopr; /* count of partial output records */
1360Sstevel@tonic-gate static unsigned long long ntrunc; /* count of truncated input lines */
1370Sstevel@tonic-gate static unsigned long long nbad; /* count of bad records since last */
1380Sstevel@tonic-gate /* good one */
1390Sstevel@tonic-gate static int files; /* number of input files to concatenate (tape only) */
1400Sstevel@tonic-gate static off_t skip; /* number of input records to skip */
1410Sstevel@tonic-gate static off_t iseekn; /* number of input records to seek past */
1420Sstevel@tonic-gate static off_t oseekn; /* number of output records to seek past */
1430Sstevel@tonic-gate static unsigned long long count; /* number of input records to copy */
1440Sstevel@tonic-gate /* (0 = all) */
1450Sstevel@tonic-gate static int trantype; /* BSD or SVr4 compatible EBCDIC */
1460Sstevel@tonic-gate
1470Sstevel@tonic-gate static char *string; /* command arg pointer */
1480Sstevel@tonic-gate static char *ifile; /* input file name pointer */
1490Sstevel@tonic-gate static char *ofile; /* output file name pointer */
1500Sstevel@tonic-gate static unsigned char *ibuf; /* input buffer pointer */
1510Sstevel@tonic-gate static unsigned char *obuf; /* output buffer pointer */
1520Sstevel@tonic-gate
1530Sstevel@tonic-gate /* This is an EBCDIC to ASCII conversion table */
1540Sstevel@tonic-gate /* from a proposed BTL standard April 16, 1979 */
1550Sstevel@tonic-gate
1560Sstevel@tonic-gate static unsigned char svr4_etoa [] =
1570Sstevel@tonic-gate {
1580Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
1590Sstevel@tonic-gate 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
1600Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
1610Sstevel@tonic-gate 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
1620Sstevel@tonic-gate 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
1630Sstevel@tonic-gate 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
1640Sstevel@tonic-gate 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
1650Sstevel@tonic-gate 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
1660Sstevel@tonic-gate 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
1670Sstevel@tonic-gate 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
1680Sstevel@tonic-gate 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
1690Sstevel@tonic-gate 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
1700Sstevel@tonic-gate 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
1710Sstevel@tonic-gate 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
1720Sstevel@tonic-gate 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
1730Sstevel@tonic-gate 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
1740Sstevel@tonic-gate 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
1750Sstevel@tonic-gate 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
1760Sstevel@tonic-gate 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
1770Sstevel@tonic-gate 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
1780Sstevel@tonic-gate 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
1790Sstevel@tonic-gate 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
1800Sstevel@tonic-gate 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
1810Sstevel@tonic-gate 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
1820Sstevel@tonic-gate 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
1830Sstevel@tonic-gate 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
1840Sstevel@tonic-gate 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
1850Sstevel@tonic-gate 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
1860Sstevel@tonic-gate 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
1870Sstevel@tonic-gate 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
1880Sstevel@tonic-gate 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
1890Sstevel@tonic-gate 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
1900Sstevel@tonic-gate };
1910Sstevel@tonic-gate
1920Sstevel@tonic-gate /* This is an ASCII to EBCDIC conversion table */
1930Sstevel@tonic-gate /* from a proposed BTL standard April 16, 1979 */
1940Sstevel@tonic-gate
1950Sstevel@tonic-gate static unsigned char svr4_atoe [] =
1960Sstevel@tonic-gate {
1970Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
1980Sstevel@tonic-gate 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
1990Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
2000Sstevel@tonic-gate 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
2010Sstevel@tonic-gate 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
2020Sstevel@tonic-gate 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
2030Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
2040Sstevel@tonic-gate 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
2050Sstevel@tonic-gate 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
2060Sstevel@tonic-gate 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
2070Sstevel@tonic-gate 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
2080Sstevel@tonic-gate 0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155,
2090Sstevel@tonic-gate 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
2100Sstevel@tonic-gate 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
2110Sstevel@tonic-gate 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
2120Sstevel@tonic-gate 0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007,
2130Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
2140Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
2150Sstevel@tonic-gate 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
2160Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
2170Sstevel@tonic-gate 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
2180Sstevel@tonic-gate 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
2190Sstevel@tonic-gate 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
2200Sstevel@tonic-gate 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
2210Sstevel@tonic-gate 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
2220Sstevel@tonic-gate 0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236,
2230Sstevel@tonic-gate 0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257,
2240Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
2250Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277,
2260Sstevel@tonic-gate 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
2270Sstevel@tonic-gate 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
2280Sstevel@tonic-gate 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
2290Sstevel@tonic-gate };
2300Sstevel@tonic-gate
2310Sstevel@tonic-gate /* Table for ASCII to IBM (alternate EBCDIC) code conversion */
2320Sstevel@tonic-gate
2330Sstevel@tonic-gate static unsigned char svr4_atoibm[] =
2340Sstevel@tonic-gate {
2350Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
2360Sstevel@tonic-gate 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
2370Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
2380Sstevel@tonic-gate 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
2390Sstevel@tonic-gate 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
2400Sstevel@tonic-gate 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
2410Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
2420Sstevel@tonic-gate 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
2430Sstevel@tonic-gate 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
2440Sstevel@tonic-gate 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
2450Sstevel@tonic-gate 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
2460Sstevel@tonic-gate 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
2470Sstevel@tonic-gate 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
2480Sstevel@tonic-gate 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
2490Sstevel@tonic-gate 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
2500Sstevel@tonic-gate 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
2510Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
2520Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
2530Sstevel@tonic-gate 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
2540Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
2550Sstevel@tonic-gate 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
2560Sstevel@tonic-gate 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
2570Sstevel@tonic-gate 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
2580Sstevel@tonic-gate 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
2590Sstevel@tonic-gate 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
2600Sstevel@tonic-gate 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
2610Sstevel@tonic-gate 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
2620Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
2630Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
2640Sstevel@tonic-gate 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
2650Sstevel@tonic-gate 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
2660Sstevel@tonic-gate 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
2670Sstevel@tonic-gate };
2680Sstevel@tonic-gate
2690Sstevel@tonic-gate /* Table for conversion of ASCII to lower case ASCII */
2700Sstevel@tonic-gate
2710Sstevel@tonic-gate static unsigned char utol[] =
2720Sstevel@tonic-gate {
2730Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
2740Sstevel@tonic-gate 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
2750Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
2760Sstevel@tonic-gate 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
2770Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
2780Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
2790Sstevel@tonic-gate 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
2800Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
2810Sstevel@tonic-gate 0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
2820Sstevel@tonic-gate 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
2830Sstevel@tonic-gate 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
2840Sstevel@tonic-gate 0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
2850Sstevel@tonic-gate 0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
2860Sstevel@tonic-gate 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
2870Sstevel@tonic-gate 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
2880Sstevel@tonic-gate 0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
2890Sstevel@tonic-gate 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
2900Sstevel@tonic-gate 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
2910Sstevel@tonic-gate 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
2920Sstevel@tonic-gate 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
2930Sstevel@tonic-gate 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
2940Sstevel@tonic-gate 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
2950Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
2960Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
2970Sstevel@tonic-gate 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
2980Sstevel@tonic-gate 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
2990Sstevel@tonic-gate 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
3000Sstevel@tonic-gate 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
3010Sstevel@tonic-gate 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
3020Sstevel@tonic-gate 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
3030Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
3040Sstevel@tonic-gate 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
3050Sstevel@tonic-gate };
3060Sstevel@tonic-gate
3070Sstevel@tonic-gate /* Table for conversion of ASCII to upper case ASCII */
3080Sstevel@tonic-gate
3090Sstevel@tonic-gate static unsigned char ltou[] =
3100Sstevel@tonic-gate {
3110Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
3120Sstevel@tonic-gate 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
3130Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
3140Sstevel@tonic-gate 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
3150Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
3160Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
3170Sstevel@tonic-gate 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
3180Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
3190Sstevel@tonic-gate 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
3200Sstevel@tonic-gate 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
3210Sstevel@tonic-gate 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
3220Sstevel@tonic-gate 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
3230Sstevel@tonic-gate 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
3240Sstevel@tonic-gate 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
3250Sstevel@tonic-gate 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
3260Sstevel@tonic-gate 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
3270Sstevel@tonic-gate 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
3280Sstevel@tonic-gate 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
3290Sstevel@tonic-gate 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
3300Sstevel@tonic-gate 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
3310Sstevel@tonic-gate 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
3320Sstevel@tonic-gate 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
3330Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
3340Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
3350Sstevel@tonic-gate 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
3360Sstevel@tonic-gate 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
3370Sstevel@tonic-gate 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
3380Sstevel@tonic-gate 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
3390Sstevel@tonic-gate 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
3400Sstevel@tonic-gate 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
3410Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
3420Sstevel@tonic-gate 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
3430Sstevel@tonic-gate };
3440Sstevel@tonic-gate
3450Sstevel@tonic-gate /* BSD-compatible EBCDIC to ASCII translate table */
3460Sstevel@tonic-gate
3470Sstevel@tonic-gate static unsigned char bsd_etoa[] =
3480Sstevel@tonic-gate {
3490Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
3500Sstevel@tonic-gate 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
3510Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
3520Sstevel@tonic-gate 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
3530Sstevel@tonic-gate 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
3540Sstevel@tonic-gate 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
3550Sstevel@tonic-gate 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
3560Sstevel@tonic-gate 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
3570Sstevel@tonic-gate 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
3580Sstevel@tonic-gate 0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041,
3590Sstevel@tonic-gate 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
3600Sstevel@tonic-gate 0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136,
3610Sstevel@tonic-gate 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
3620Sstevel@tonic-gate 0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077,
3630Sstevel@tonic-gate 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
3640Sstevel@tonic-gate 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
3650Sstevel@tonic-gate 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
3660Sstevel@tonic-gate 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
3670Sstevel@tonic-gate 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
3680Sstevel@tonic-gate 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
3690Sstevel@tonic-gate 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
3700Sstevel@tonic-gate 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
3710Sstevel@tonic-gate 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
3720Sstevel@tonic-gate 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
3730Sstevel@tonic-gate 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
3740Sstevel@tonic-gate 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
3750Sstevel@tonic-gate 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
3760Sstevel@tonic-gate 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
3770Sstevel@tonic-gate 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
3780Sstevel@tonic-gate 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
3790Sstevel@tonic-gate 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
3800Sstevel@tonic-gate 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
3810Sstevel@tonic-gate };
3820Sstevel@tonic-gate
3830Sstevel@tonic-gate /* BSD-compatible ASCII to EBCDIC translate table */
3840Sstevel@tonic-gate
3850Sstevel@tonic-gate static unsigned char bsd_atoe[] =
3860Sstevel@tonic-gate {
3870Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
3880Sstevel@tonic-gate 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
3890Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
3900Sstevel@tonic-gate 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
3910Sstevel@tonic-gate 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
3920Sstevel@tonic-gate 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
3930Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
3940Sstevel@tonic-gate 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
3950Sstevel@tonic-gate 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
3960Sstevel@tonic-gate 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
3970Sstevel@tonic-gate 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
3980Sstevel@tonic-gate 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
3990Sstevel@tonic-gate 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
4000Sstevel@tonic-gate 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
4010Sstevel@tonic-gate 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
4020Sstevel@tonic-gate 0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007,
4030Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
4040Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
4050Sstevel@tonic-gate 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
4060Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
4070Sstevel@tonic-gate 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
4080Sstevel@tonic-gate 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
4090Sstevel@tonic-gate 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
4100Sstevel@tonic-gate 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
4110Sstevel@tonic-gate 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
4120Sstevel@tonic-gate 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
4130Sstevel@tonic-gate 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
4140Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
4150Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
4160Sstevel@tonic-gate 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
4170Sstevel@tonic-gate 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
4180Sstevel@tonic-gate 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
4190Sstevel@tonic-gate };
4200Sstevel@tonic-gate
4210Sstevel@tonic-gate /* BSD-compatible ASCII to IBM translate table */
4220Sstevel@tonic-gate
4230Sstevel@tonic-gate static unsigned char bsd_atoibm[] =
4240Sstevel@tonic-gate {
4250Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
4260Sstevel@tonic-gate 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
4270Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
4280Sstevel@tonic-gate 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
4290Sstevel@tonic-gate 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
4300Sstevel@tonic-gate 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
4310Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
4320Sstevel@tonic-gate 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
4330Sstevel@tonic-gate 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
4340Sstevel@tonic-gate 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
4350Sstevel@tonic-gate 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
4360Sstevel@tonic-gate 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
4370Sstevel@tonic-gate 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
4380Sstevel@tonic-gate 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
4390Sstevel@tonic-gate 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
4400Sstevel@tonic-gate 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
4410Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
4420Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
4430Sstevel@tonic-gate 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
4440Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
4450Sstevel@tonic-gate 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
4460Sstevel@tonic-gate 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
4470Sstevel@tonic-gate 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
4480Sstevel@tonic-gate 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
4490Sstevel@tonic-gate 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
4500Sstevel@tonic-gate 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
4510Sstevel@tonic-gate 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
4520Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
4530Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
4540Sstevel@tonic-gate 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
4550Sstevel@tonic-gate 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
4560Sstevel@tonic-gate 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
4570Sstevel@tonic-gate };
4580Sstevel@tonic-gate
4590Sstevel@tonic-gate /* set up to use SVr4 ascii-ebcdic translation by default */
4600Sstevel@tonic-gate
4610Sstevel@tonic-gate static unsigned char *atoe = svr4_atoe;
4620Sstevel@tonic-gate static unsigned char *etoa = svr4_etoa;
4630Sstevel@tonic-gate static unsigned char *atoibm = svr4_atoibm;
4640Sstevel@tonic-gate
4650Sstevel@tonic-gate
466*212Scf46844 int
main(int argc,char ** argv)467*212Scf46844 main(int argc, char **argv)
4680Sstevel@tonic-gate {
4690Sstevel@tonic-gate unsigned char *ip, *op; /* input and output buffer pointers */
4700Sstevel@tonic-gate int c; /* character counter */
4710Sstevel@tonic-gate int ic; /* input character */
4720Sstevel@tonic-gate int conv; /* conversion option code */
4730Sstevel@tonic-gate int trunc; /* whether output file is truncated */
4740Sstevel@tonic-gate struct stat file_stat;
4750Sstevel@tonic-gate
4760Sstevel@tonic-gate /* Set option defaults */
4770Sstevel@tonic-gate
4780Sstevel@tonic-gate ibs = BSIZE;
4790Sstevel@tonic-gate obs = BSIZE;
4800Sstevel@tonic-gate files = 1;
4810Sstevel@tonic-gate conv = COPY;
4820Sstevel@tonic-gate trunc = 1; /* default: truncate output file */
4830Sstevel@tonic-gate trantype = SVR4XLATE; /* use SVR4 EBCDIC by default */
4840Sstevel@tonic-gate
4850Sstevel@tonic-gate /* Parse command options */
4860Sstevel@tonic-gate
4870Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
4880Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
4890Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
4900Sstevel@tonic-gate #endif
4910Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
4920Sstevel@tonic-gate
4930Sstevel@tonic-gate while ((c = getopt(argc, argv, "")) != EOF)
4940Sstevel@tonic-gate switch (c) {
4950Sstevel@tonic-gate case '?':
4960Sstevel@tonic-gate (void) fprintf(stderr, USAGE);
4970Sstevel@tonic-gate exit(2);
4980Sstevel@tonic-gate }
4990Sstevel@tonic-gate
5000Sstevel@tonic-gate /* not getopt()'ed because dd has no options but only operand(s) */
5010Sstevel@tonic-gate
5020Sstevel@tonic-gate for (c = optind; c < argc; c++)
5030Sstevel@tonic-gate {
5040Sstevel@tonic-gate string = argv[c];
5050Sstevel@tonic-gate if (match("ibs="))
5060Sstevel@tonic-gate {
5070Sstevel@tonic-gate ibs = (unsigned)number(BIG);
5080Sstevel@tonic-gate continue;
5090Sstevel@tonic-gate }
5100Sstevel@tonic-gate if (match("obs="))
5110Sstevel@tonic-gate {
5120Sstevel@tonic-gate obs = (unsigned)number(BIG);
5130Sstevel@tonic-gate continue;
5140Sstevel@tonic-gate }
5150Sstevel@tonic-gate if (match("cbs="))
5160Sstevel@tonic-gate {
5170Sstevel@tonic-gate cbs = (unsigned)number(BIG);
5180Sstevel@tonic-gate continue;
5190Sstevel@tonic-gate }
5200Sstevel@tonic-gate if (match("bs="))
5210Sstevel@tonic-gate {
5220Sstevel@tonic-gate bs = (unsigned)number(BIG);
5230Sstevel@tonic-gate continue;
5240Sstevel@tonic-gate }
5250Sstevel@tonic-gate if (match("if="))
5260Sstevel@tonic-gate {
5270Sstevel@tonic-gate ifile = string;
5280Sstevel@tonic-gate continue;
5290Sstevel@tonic-gate }
5300Sstevel@tonic-gate if (match("of="))
5310Sstevel@tonic-gate {
5320Sstevel@tonic-gate ofile = string;
5330Sstevel@tonic-gate continue;
5340Sstevel@tonic-gate }
5350Sstevel@tonic-gate if (match("skip="))
5360Sstevel@tonic-gate {
5370Sstevel@tonic-gate skip = number(BIG);
5380Sstevel@tonic-gate continue;
5390Sstevel@tonic-gate }
5400Sstevel@tonic-gate if (match("iseek="))
5410Sstevel@tonic-gate {
5420Sstevel@tonic-gate iseekn = number(BIG);
5430Sstevel@tonic-gate continue;
5440Sstevel@tonic-gate }
5450Sstevel@tonic-gate if (match("oseek="))
5460Sstevel@tonic-gate {
5470Sstevel@tonic-gate oseekn = number(BIG);
5480Sstevel@tonic-gate continue;
5490Sstevel@tonic-gate }
5500Sstevel@tonic-gate if (match("seek=")) /* retained for compatibility */
5510Sstevel@tonic-gate {
5520Sstevel@tonic-gate oseekn = number(BIG);
5530Sstevel@tonic-gate continue;
5540Sstevel@tonic-gate }
5550Sstevel@tonic-gate if (match("count="))
5560Sstevel@tonic-gate {
5570Sstevel@tonic-gate count = number(BIG);
5580Sstevel@tonic-gate continue;
5590Sstevel@tonic-gate }
5600Sstevel@tonic-gate if (match("files="))
5610Sstevel@tonic-gate {
5620Sstevel@tonic-gate files = (int)number(BIG);
5630Sstevel@tonic-gate continue;
5640Sstevel@tonic-gate }
5650Sstevel@tonic-gate if (match("conv="))
5660Sstevel@tonic-gate {
5670Sstevel@tonic-gate for (;;)
5680Sstevel@tonic-gate {
5690Sstevel@tonic-gate if (match(","))
5700Sstevel@tonic-gate {
5710Sstevel@tonic-gate continue;
5720Sstevel@tonic-gate }
5730Sstevel@tonic-gate if (*string == '\0')
5740Sstevel@tonic-gate {
5750Sstevel@tonic-gate break;
5760Sstevel@tonic-gate }
5770Sstevel@tonic-gate if (match("block"))
5780Sstevel@tonic-gate {
5790Sstevel@tonic-gate conv = BLOCK;
5800Sstevel@tonic-gate continue;
5810Sstevel@tonic-gate }
5820Sstevel@tonic-gate if (match("unblock"))
5830Sstevel@tonic-gate {
5840Sstevel@tonic-gate conv = UNBLOCK;
5850Sstevel@tonic-gate continue;
5860Sstevel@tonic-gate }
5870Sstevel@tonic-gate
5880Sstevel@tonic-gate /* ebcdicb, ibmb, and asciib must precede */
5890Sstevel@tonic-gate /* ebcdic, ibm, and ascii in this test */
5900Sstevel@tonic-gate
5910Sstevel@tonic-gate if (match("ebcdicb"))
5920Sstevel@tonic-gate {
5930Sstevel@tonic-gate conv = EBCDIC;
5940Sstevel@tonic-gate trantype = BSDXLATE;
5950Sstevel@tonic-gate continue;
5960Sstevel@tonic-gate }
5970Sstevel@tonic-gate if (match("ibmb"))
5980Sstevel@tonic-gate {
5990Sstevel@tonic-gate conv = IBM;
6000Sstevel@tonic-gate trantype = BSDXLATE;
6010Sstevel@tonic-gate continue;
6020Sstevel@tonic-gate }
6030Sstevel@tonic-gate if (match("asciib"))
6040Sstevel@tonic-gate {
6050Sstevel@tonic-gate conv = ASCII;
6060Sstevel@tonic-gate trantype = BSDXLATE;
6070Sstevel@tonic-gate continue;
6080Sstevel@tonic-gate }
6090Sstevel@tonic-gate if (match("ebcdic"))
6100Sstevel@tonic-gate {
6110Sstevel@tonic-gate conv = EBCDIC;
6120Sstevel@tonic-gate trantype = SVR4XLATE;
6130Sstevel@tonic-gate continue;
6140Sstevel@tonic-gate }
6150Sstevel@tonic-gate if (match("ibm"))
6160Sstevel@tonic-gate {
6170Sstevel@tonic-gate conv = IBM;
6180Sstevel@tonic-gate trantype = SVR4XLATE;
6190Sstevel@tonic-gate continue;
6200Sstevel@tonic-gate }
6210Sstevel@tonic-gate if (match("ascii"))
6220Sstevel@tonic-gate {
6230Sstevel@tonic-gate conv = ASCII;
6240Sstevel@tonic-gate trantype = SVR4XLATE;
6250Sstevel@tonic-gate continue;
6260Sstevel@tonic-gate }
6270Sstevel@tonic-gate if (match("lcase"))
6280Sstevel@tonic-gate {
6290Sstevel@tonic-gate cflag |= LCASE;
6300Sstevel@tonic-gate continue;
6310Sstevel@tonic-gate }
6320Sstevel@tonic-gate if (match("ucase"))
6330Sstevel@tonic-gate {
6340Sstevel@tonic-gate cflag |= UCASE;
6350Sstevel@tonic-gate continue;
6360Sstevel@tonic-gate }
6370Sstevel@tonic-gate if (match("swab"))
6380Sstevel@tonic-gate {
6390Sstevel@tonic-gate cflag |= SWAB;
6400Sstevel@tonic-gate continue;
6410Sstevel@tonic-gate }
6420Sstevel@tonic-gate if (match("noerror"))
6430Sstevel@tonic-gate {
6440Sstevel@tonic-gate cflag |= NERR;
6450Sstevel@tonic-gate continue;
6460Sstevel@tonic-gate }
6470Sstevel@tonic-gate if (match("notrunc"))
6480Sstevel@tonic-gate {
6490Sstevel@tonic-gate trunc = 0;
6500Sstevel@tonic-gate continue;
6510Sstevel@tonic-gate }
6520Sstevel@tonic-gate if (match("sync"))
6530Sstevel@tonic-gate {
6540Sstevel@tonic-gate cflag |= SYNC;
6550Sstevel@tonic-gate continue;
6560Sstevel@tonic-gate }
6570Sstevel@tonic-gate goto badarg;
6580Sstevel@tonic-gate }
6590Sstevel@tonic-gate continue;
6600Sstevel@tonic-gate }
6610Sstevel@tonic-gate badarg:
6620Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s \"%s\"\n",
6630Sstevel@tonic-gate gettext("bad argument:"), string);
6640Sstevel@tonic-gate exit(2);
6650Sstevel@tonic-gate }
6660Sstevel@tonic-gate
6670Sstevel@tonic-gate /* Perform consistency checks on options, decode strange conventions */
6680Sstevel@tonic-gate
6690Sstevel@tonic-gate if (bs)
6700Sstevel@tonic-gate {
6710Sstevel@tonic-gate ibs = obs = bs;
6720Sstevel@tonic-gate }
6730Sstevel@tonic-gate if ((ibs == 0) || (obs == 0))
6740Sstevel@tonic-gate {
6750Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s\n",
6760Sstevel@tonic-gate gettext("buffer sizes cannot be zero"));
6770Sstevel@tonic-gate exit(2);
6780Sstevel@tonic-gate }
6790Sstevel@tonic-gate if (conv == COPY)
6800Sstevel@tonic-gate {
6810Sstevel@tonic-gate if ((bs == 0) || (cflag&(LCASE|UCASE)))
6820Sstevel@tonic-gate {
6830Sstevel@tonic-gate conv = REBLOCK;
6840Sstevel@tonic-gate }
6850Sstevel@tonic-gate }
6860Sstevel@tonic-gate if (cbs == 0)
6870Sstevel@tonic-gate {
6880Sstevel@tonic-gate switch (conv)
6890Sstevel@tonic-gate {
6900Sstevel@tonic-gate case BLOCK:
6910Sstevel@tonic-gate case UNBLOCK:
6920Sstevel@tonic-gate conv = REBLOCK;
6930Sstevel@tonic-gate break;
6940Sstevel@tonic-gate
6950Sstevel@tonic-gate case ASCII:
6960Sstevel@tonic-gate conv = NBASCII;
6970Sstevel@tonic-gate break;
6980Sstevel@tonic-gate
6990Sstevel@tonic-gate case EBCDIC:
7000Sstevel@tonic-gate conv = NBEBCDIC;
7010Sstevel@tonic-gate break;
7020Sstevel@tonic-gate
7030Sstevel@tonic-gate case IBM:
7040Sstevel@tonic-gate conv = NBIBM;
7050Sstevel@tonic-gate break;
7060Sstevel@tonic-gate }
7070Sstevel@tonic-gate }
7080Sstevel@tonic-gate
7090Sstevel@tonic-gate /* Expand options into lower and upper case versions if necessary */
7100Sstevel@tonic-gate
7110Sstevel@tonic-gate switch (conv)
7120Sstevel@tonic-gate {
7130Sstevel@tonic-gate case REBLOCK:
7140Sstevel@tonic-gate if (cflag&LCASE)
7150Sstevel@tonic-gate conv = LCREBLOCK;
7160Sstevel@tonic-gate else if (cflag&UCASE)
7170Sstevel@tonic-gate conv = UCREBLOCK;
7180Sstevel@tonic-gate break;
7190Sstevel@tonic-gate
7200Sstevel@tonic-gate case UNBLOCK:
7210Sstevel@tonic-gate if (cflag&LCASE)
7220Sstevel@tonic-gate conv = LCUNBLOCK;
7230Sstevel@tonic-gate else if (cflag&UCASE)
7240Sstevel@tonic-gate conv = UCUNBLOCK;
7250Sstevel@tonic-gate break;
7260Sstevel@tonic-gate
7270Sstevel@tonic-gate case BLOCK:
7280Sstevel@tonic-gate if (cflag&LCASE)
7290Sstevel@tonic-gate conv = LCBLOCK;
7300Sstevel@tonic-gate else if (cflag&UCASE)
7310Sstevel@tonic-gate conv = UCBLOCK;
7320Sstevel@tonic-gate break;
7330Sstevel@tonic-gate
7340Sstevel@tonic-gate case ASCII:
7350Sstevel@tonic-gate if (cflag&LCASE)
7360Sstevel@tonic-gate conv = LCASCII;
7370Sstevel@tonic-gate else if (cflag&UCASE)
7380Sstevel@tonic-gate conv = UCASCII;
7390Sstevel@tonic-gate break;
7400Sstevel@tonic-gate
7410Sstevel@tonic-gate case NBASCII:
7420Sstevel@tonic-gate if (cflag&LCASE)
7430Sstevel@tonic-gate conv = LCNBASCII;
7440Sstevel@tonic-gate else if (cflag&UCASE)
7450Sstevel@tonic-gate conv = UCNBASCII;
7460Sstevel@tonic-gate break;
7470Sstevel@tonic-gate
7480Sstevel@tonic-gate case EBCDIC:
7490Sstevel@tonic-gate if (cflag&LCASE)
7500Sstevel@tonic-gate conv = LCEBCDIC;
7510Sstevel@tonic-gate else if (cflag&UCASE)
7520Sstevel@tonic-gate conv = UCEBCDIC;
7530Sstevel@tonic-gate break;
7540Sstevel@tonic-gate
7550Sstevel@tonic-gate case NBEBCDIC:
7560Sstevel@tonic-gate if (cflag&LCASE)
7570Sstevel@tonic-gate conv = LCNBEBCDIC;
7580Sstevel@tonic-gate else if (cflag&UCASE)
7590Sstevel@tonic-gate conv = UCNBEBCDIC;
7600Sstevel@tonic-gate break;
7610Sstevel@tonic-gate
7620Sstevel@tonic-gate case IBM:
7630Sstevel@tonic-gate if (cflag&LCASE)
7640Sstevel@tonic-gate conv = LCIBM;
7650Sstevel@tonic-gate else if (cflag&UCASE)
7660Sstevel@tonic-gate conv = UCIBM;
7670Sstevel@tonic-gate break;
7680Sstevel@tonic-gate
7690Sstevel@tonic-gate case NBIBM:
7700Sstevel@tonic-gate if (cflag&LCASE)
7710Sstevel@tonic-gate conv = LCNBIBM;
7720Sstevel@tonic-gate else if (cflag&UCASE)
7730Sstevel@tonic-gate conv = UCNBIBM;
7740Sstevel@tonic-gate break;
7750Sstevel@tonic-gate }
7760Sstevel@tonic-gate
7770Sstevel@tonic-gate /* If BSD-compatible translation is selected, change the tables */
7780Sstevel@tonic-gate
7790Sstevel@tonic-gate if (trantype == BSDXLATE) {
7800Sstevel@tonic-gate atoe = bsd_atoe;
7810Sstevel@tonic-gate atoibm = bsd_atoibm;
7820Sstevel@tonic-gate etoa = bsd_etoa;
7830Sstevel@tonic-gate }
7840Sstevel@tonic-gate /* Open the input file, or duplicate standard input */
7850Sstevel@tonic-gate
7860Sstevel@tonic-gate ibf = -1;
7870Sstevel@tonic-gate if (ifile)
7880Sstevel@tonic-gate {
7890Sstevel@tonic-gate ibf = open(ifile, 0);
7900Sstevel@tonic-gate }
7910Sstevel@tonic-gate #ifndef STANDALONE
7920Sstevel@tonic-gate else
7930Sstevel@tonic-gate {
7940Sstevel@tonic-gate ifile = "";
7950Sstevel@tonic-gate ibf = dup(0);
7960Sstevel@tonic-gate }
7970Sstevel@tonic-gate #endif
7980Sstevel@tonic-gate if (ibf == -1)
7990Sstevel@tonic-gate {
8000Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s: ", ifile);
8010Sstevel@tonic-gate perror("open");
8020Sstevel@tonic-gate exit(2);
8030Sstevel@tonic-gate }
8040Sstevel@tonic-gate
8050Sstevel@tonic-gate /* Open the output file, or duplicate standard output */
8060Sstevel@tonic-gate
8070Sstevel@tonic-gate obf = -1;
8080Sstevel@tonic-gate if (ofile)
8090Sstevel@tonic-gate {
8100Sstevel@tonic-gate if (trunc == 0) /* do not truncate output file */
8110Sstevel@tonic-gate obf = open(ofile, (O_WRONLY|O_CREAT),
8120Sstevel@tonic-gate (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
8130Sstevel@tonic-gate else if (oseekn && (trunc == 1))
8140Sstevel@tonic-gate {
8150Sstevel@tonic-gate obf = open(ofile, O_WRONLY|O_CREAT,
8160Sstevel@tonic-gate (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
8170Sstevel@tonic-gate if (obf == -1)
8180Sstevel@tonic-gate {
8190Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s: ", ofile);
8200Sstevel@tonic-gate perror("open");
8210Sstevel@tonic-gate exit(2);
8220Sstevel@tonic-gate }
8230Sstevel@tonic-gate (void) fstat(obf, &file_stat);
8240Sstevel@tonic-gate if (((file_stat.st_mode & S_IFMT) == S_IFREG) &&
8250Sstevel@tonic-gate (ftruncate(obf, (((off_t)oseekn) * ((off_t)obs)))
8260Sstevel@tonic-gate == -1))
8270Sstevel@tonic-gate {
8280Sstevel@tonic-gate perror("ftruncate");
8290Sstevel@tonic-gate exit(2);
8300Sstevel@tonic-gate }
8310Sstevel@tonic-gate }
8320Sstevel@tonic-gate else
8330Sstevel@tonic-gate obf = creat(ofile,
8340Sstevel@tonic-gate (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH));
8350Sstevel@tonic-gate }
8360Sstevel@tonic-gate #ifndef STANDALONE
8370Sstevel@tonic-gate else
8380Sstevel@tonic-gate {
8390Sstevel@tonic-gate ofile = "";
8400Sstevel@tonic-gate obf = dup(1);
8410Sstevel@tonic-gate }
8420Sstevel@tonic-gate #endif
8430Sstevel@tonic-gate if (obf == -1)
8440Sstevel@tonic-gate {
8450Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s: ", ofile);
8460Sstevel@tonic-gate perror("open");
8470Sstevel@tonic-gate exit(2);
8480Sstevel@tonic-gate }
8490Sstevel@tonic-gate
8500Sstevel@tonic-gate /* Expand memory to get an input buffer */
8510Sstevel@tonic-gate
8520Sstevel@tonic-gate ibuf = (unsigned char *)valloc(ibs + 10);
8530Sstevel@tonic-gate
8540Sstevel@tonic-gate /* If no conversions, the input buffer is the output buffer */
8550Sstevel@tonic-gate
8560Sstevel@tonic-gate if (conv == COPY)
8570Sstevel@tonic-gate {
8580Sstevel@tonic-gate obuf = ibuf;
8590Sstevel@tonic-gate }
8600Sstevel@tonic-gate
8610Sstevel@tonic-gate /* Expand memory to get an output buffer. Leave enough room at the */
8620Sstevel@tonic-gate /* end to convert a logical record when doing block conversions. */
8630Sstevel@tonic-gate
8640Sstevel@tonic-gate else
8650Sstevel@tonic-gate {
8660Sstevel@tonic-gate obuf = (unsigned char *)valloc(obs + cbs + 10);
8670Sstevel@tonic-gate }
8680Sstevel@tonic-gate if ((ibuf == (unsigned char *)NULL) || (obuf == (unsigned char *)NULL))
8690Sstevel@tonic-gate {
8700Sstevel@tonic-gate (void) fprintf(stderr,
8710Sstevel@tonic-gate "dd: %s\n", gettext("not enough memory"));
8720Sstevel@tonic-gate exit(2);
8730Sstevel@tonic-gate }
8740Sstevel@tonic-gate
8750Sstevel@tonic-gate /* Enable a statistics message on SIGINT */
8760Sstevel@tonic-gate
8770Sstevel@tonic-gate #ifndef STANDALONE
8780Sstevel@tonic-gate if (signal(SIGINT, SIG_IGN) != SIG_IGN)
8790Sstevel@tonic-gate {
8800Sstevel@tonic-gate (void) signal(SIGINT, term);
8810Sstevel@tonic-gate }
8820Sstevel@tonic-gate #endif
8830Sstevel@tonic-gate /* Skip input blocks */
8840Sstevel@tonic-gate
8850Sstevel@tonic-gate while (skip)
8860Sstevel@tonic-gate {
8870Sstevel@tonic-gate ibc = read(ibf, (char *)ibuf, ibs);
8880Sstevel@tonic-gate if (ibc == (unsigned)-1)
8890Sstevel@tonic-gate {
8900Sstevel@tonic-gate if (++nbad > BADLIMIT)
8910Sstevel@tonic-gate {
8920Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s\n",
8930Sstevel@tonic-gate gettext("skip failed"));
8940Sstevel@tonic-gate exit(2);
8950Sstevel@tonic-gate }
8960Sstevel@tonic-gate else
8970Sstevel@tonic-gate {
8980Sstevel@tonic-gate perror("read");
8990Sstevel@tonic-gate }
9000Sstevel@tonic-gate }
9010Sstevel@tonic-gate else
9020Sstevel@tonic-gate {
9030Sstevel@tonic-gate if (ibc == 0)
9040Sstevel@tonic-gate {
9050Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s\n",
9060Sstevel@tonic-gate gettext("cannot skip past end-of-file"));
9070Sstevel@tonic-gate exit(3);
9080Sstevel@tonic-gate }
9090Sstevel@tonic-gate else
9100Sstevel@tonic-gate {
9110Sstevel@tonic-gate nbad = 0;
9120Sstevel@tonic-gate }
9130Sstevel@tonic-gate }
9140Sstevel@tonic-gate skip--;
9150Sstevel@tonic-gate }
9160Sstevel@tonic-gate
9170Sstevel@tonic-gate /* Seek past input blocks */
9180Sstevel@tonic-gate
9190Sstevel@tonic-gate if (iseekn && lseek(ibf, (((off_t)iseekn) * ((off_t)ibs)), 1) == -1)
9200Sstevel@tonic-gate {
9210Sstevel@tonic-gate perror("lseek");
9220Sstevel@tonic-gate exit(2);
9230Sstevel@tonic-gate }
9240Sstevel@tonic-gate
9250Sstevel@tonic-gate /* Seek past output blocks */
9260Sstevel@tonic-gate
9270Sstevel@tonic-gate if (oseekn && lseek(obf, (((off_t)oseekn) * ((off_t)obs)), 1) == -1)
9280Sstevel@tonic-gate {
9290Sstevel@tonic-gate perror("lseek");
9300Sstevel@tonic-gate exit(2);
9310Sstevel@tonic-gate }
9320Sstevel@tonic-gate
9330Sstevel@tonic-gate /* Initialize all buffer pointers */
9340Sstevel@tonic-gate
9350Sstevel@tonic-gate skipf = 0; /* not skipping an input line */
9360Sstevel@tonic-gate ibc = 0; /* no input characters yet */
9370Sstevel@tonic-gate obc = 0; /* no output characters yet */
9380Sstevel@tonic-gate cbc = 0; /* the conversion buffer is empty */
9390Sstevel@tonic-gate op = obuf; /* point to the output buffer */
9400Sstevel@tonic-gate
9410Sstevel@tonic-gate /* Read and convert input blocks until end of file(s) */
9420Sstevel@tonic-gate
9430Sstevel@tonic-gate for (;;)
9440Sstevel@tonic-gate {
9450Sstevel@tonic-gate if ((count == 0) || (nifr+nipr < count))
9460Sstevel@tonic-gate {
9470Sstevel@tonic-gate /* If proceed on error is enabled, zero the input buffer */
9480Sstevel@tonic-gate
9490Sstevel@tonic-gate if (cflag&NERR)
9500Sstevel@tonic-gate {
9510Sstevel@tonic-gate ip = ibuf + ibs;
9520Sstevel@tonic-gate c = ibs;
9530Sstevel@tonic-gate if (c & 1) /* if the size is odd, */
9540Sstevel@tonic-gate {
9550Sstevel@tonic-gate *--ip = 0; /* clear the odd byte */
9560Sstevel@tonic-gate }
9570Sstevel@tonic-gate if (c >>= 1) /* divide by two */
9580Sstevel@tonic-gate {
9590Sstevel@tonic-gate do { /* clear two at a time */
9600Sstevel@tonic-gate *--ip = 0;
9610Sstevel@tonic-gate *--ip = 0;
9620Sstevel@tonic-gate } while (--c);
9630Sstevel@tonic-gate }
9640Sstevel@tonic-gate }
9650Sstevel@tonic-gate
9660Sstevel@tonic-gate /* Read the next input block */
9670Sstevel@tonic-gate
9680Sstevel@tonic-gate ibc = read(ibf, (char *)ibuf, ibs);
9690Sstevel@tonic-gate
9700Sstevel@tonic-gate /* Process input errors */
9710Sstevel@tonic-gate
9720Sstevel@tonic-gate if (ibc == (unsigned)-1)
9730Sstevel@tonic-gate {
9740Sstevel@tonic-gate perror("read");
9750Sstevel@tonic-gate if (((cflag&NERR) == 0) || (++nbad > BADLIMIT))
9760Sstevel@tonic-gate {
9770Sstevel@tonic-gate while (obc)
9780Sstevel@tonic-gate {
9790Sstevel@tonic-gate (void) flsh();
9800Sstevel@tonic-gate }
9810Sstevel@tonic-gate term(2);
9820Sstevel@tonic-gate }
9830Sstevel@tonic-gate else
9840Sstevel@tonic-gate {
9850Sstevel@tonic-gate stats();
9860Sstevel@tonic-gate ibc = ibs; /* assume a full block */
9870Sstevel@tonic-gate }
9880Sstevel@tonic-gate }
9890Sstevel@tonic-gate else
9900Sstevel@tonic-gate {
9910Sstevel@tonic-gate nbad = 0;
9920Sstevel@tonic-gate }
9930Sstevel@tonic-gate }
9940Sstevel@tonic-gate
9950Sstevel@tonic-gate /* Record count satisfied, simulate end of file */
9960Sstevel@tonic-gate
9970Sstevel@tonic-gate else
9980Sstevel@tonic-gate {
9990Sstevel@tonic-gate ibc = 0;
10000Sstevel@tonic-gate files = 1;
10010Sstevel@tonic-gate }
10020Sstevel@tonic-gate
10030Sstevel@tonic-gate /* Process end of file */
10040Sstevel@tonic-gate
10050Sstevel@tonic-gate if (ibc == 0)
10060Sstevel@tonic-gate {
10070Sstevel@tonic-gate switch (conv)
10080Sstevel@tonic-gate {
10090Sstevel@tonic-gate case UNBLOCK:
10100Sstevel@tonic-gate case LCUNBLOCK:
10110Sstevel@tonic-gate case UCUNBLOCK:
10120Sstevel@tonic-gate case ASCII:
10130Sstevel@tonic-gate case LCASCII:
10140Sstevel@tonic-gate case UCASCII:
10150Sstevel@tonic-gate
10160Sstevel@tonic-gate /* Trim trailing blanks from the last line */
10170Sstevel@tonic-gate
10180Sstevel@tonic-gate if ((c = cbc) != 0)
10190Sstevel@tonic-gate {
10200Sstevel@tonic-gate do {
10210Sstevel@tonic-gate if ((*--op) != ' ')
10220Sstevel@tonic-gate {
10230Sstevel@tonic-gate op++;
10240Sstevel@tonic-gate break;
10250Sstevel@tonic-gate }
10260Sstevel@tonic-gate } while (--c);
10270Sstevel@tonic-gate *op++ = '\n';
10280Sstevel@tonic-gate obc -= cbc - c - 1;
10290Sstevel@tonic-gate cbc = 0;
10300Sstevel@tonic-gate
10310Sstevel@tonic-gate /* Flush the output buffer if full */
10320Sstevel@tonic-gate
10330Sstevel@tonic-gate while (obc >= obs)
10340Sstevel@tonic-gate {
10350Sstevel@tonic-gate op = flsh();
10360Sstevel@tonic-gate }
10370Sstevel@tonic-gate }
10380Sstevel@tonic-gate break;
10390Sstevel@tonic-gate
10400Sstevel@tonic-gate case BLOCK:
10410Sstevel@tonic-gate case LCBLOCK:
10420Sstevel@tonic-gate case UCBLOCK:
10430Sstevel@tonic-gate case EBCDIC:
10440Sstevel@tonic-gate case LCEBCDIC:
10450Sstevel@tonic-gate case UCEBCDIC:
10460Sstevel@tonic-gate case IBM:
10470Sstevel@tonic-gate case LCIBM:
10480Sstevel@tonic-gate case UCIBM:
10490Sstevel@tonic-gate
10500Sstevel@tonic-gate /* Pad trailing blanks if the last line is short */
10510Sstevel@tonic-gate
10520Sstevel@tonic-gate if (cbc)
10530Sstevel@tonic-gate {
10540Sstevel@tonic-gate obc += c = cbs - cbc;
10550Sstevel@tonic-gate cbc = 0;
10560Sstevel@tonic-gate if (c > 0)
10570Sstevel@tonic-gate {
10580Sstevel@tonic-gate /* Use the right kind of blank */
10590Sstevel@tonic-gate
10600Sstevel@tonic-gate switch (conv)
10610Sstevel@tonic-gate {
10620Sstevel@tonic-gate case BLOCK:
10630Sstevel@tonic-gate case LCBLOCK:
10640Sstevel@tonic-gate case UCBLOCK:
10650Sstevel@tonic-gate ic = ' ';
10660Sstevel@tonic-gate break;
10670Sstevel@tonic-gate
10680Sstevel@tonic-gate case EBCDIC:
10690Sstevel@tonic-gate case LCEBCDIC:
10700Sstevel@tonic-gate case UCEBCDIC:
10710Sstevel@tonic-gate ic = atoe[' '];
10720Sstevel@tonic-gate break;
10730Sstevel@tonic-gate
10740Sstevel@tonic-gate case IBM:
10750Sstevel@tonic-gate case LCIBM:
10760Sstevel@tonic-gate case UCIBM:
10770Sstevel@tonic-gate ic = atoibm[' '];
10780Sstevel@tonic-gate break;
10790Sstevel@tonic-gate }
10800Sstevel@tonic-gate
10810Sstevel@tonic-gate /* Pad with trailing blanks */
10820Sstevel@tonic-gate
10830Sstevel@tonic-gate do {
10840Sstevel@tonic-gate *op++ = ic;
10850Sstevel@tonic-gate } while (--c);
10860Sstevel@tonic-gate }
10870Sstevel@tonic-gate }
10880Sstevel@tonic-gate
10890Sstevel@tonic-gate
10900Sstevel@tonic-gate /* Flush the output buffer if full */
10910Sstevel@tonic-gate
10920Sstevel@tonic-gate while (obc >= obs)
10930Sstevel@tonic-gate {
10940Sstevel@tonic-gate op = flsh();
10950Sstevel@tonic-gate }
10960Sstevel@tonic-gate break;
10970Sstevel@tonic-gate }
10980Sstevel@tonic-gate
10990Sstevel@tonic-gate /* If no more files to read, flush the output buffer */
11000Sstevel@tonic-gate
11010Sstevel@tonic-gate if (--files <= 0)
11020Sstevel@tonic-gate {
11030Sstevel@tonic-gate (void) flsh();
11040Sstevel@tonic-gate if ((close(obf) != 0) || (fclose(stdout) != 0))
11050Sstevel@tonic-gate {
11060Sstevel@tonic-gate perror(gettext("dd: close error"));
11070Sstevel@tonic-gate exit(2);
11080Sstevel@tonic-gate }
11090Sstevel@tonic-gate term(0); /* successful exit */
11100Sstevel@tonic-gate }
11110Sstevel@tonic-gate else
11120Sstevel@tonic-gate {
11130Sstevel@tonic-gate continue; /* read the next file */
11140Sstevel@tonic-gate }
11150Sstevel@tonic-gate }
11160Sstevel@tonic-gate
11170Sstevel@tonic-gate /* Normal read, check for special cases */
11180Sstevel@tonic-gate
11190Sstevel@tonic-gate else if (ibc == ibs)
11200Sstevel@tonic-gate {
11210Sstevel@tonic-gate nifr++; /* count another full input record */
11220Sstevel@tonic-gate }
11230Sstevel@tonic-gate else
11240Sstevel@tonic-gate {
11250Sstevel@tonic-gate nipr++; /* count a partial input record */
11260Sstevel@tonic-gate
11270Sstevel@tonic-gate /* If `sync' enabled, pad nulls */
11280Sstevel@tonic-gate
11290Sstevel@tonic-gate if ((cflag&SYNC) && ((cflag&NERR) == 0))
11300Sstevel@tonic-gate {
11310Sstevel@tonic-gate c = ibs - ibc;
11320Sstevel@tonic-gate ip = ibuf + ibs;
11330Sstevel@tonic-gate do {
11340Sstevel@tonic-gate if ((conv == BLOCK) || (conv == UNBLOCK))
11350Sstevel@tonic-gate *--ip = ' ';
11360Sstevel@tonic-gate else
11370Sstevel@tonic-gate *--ip = '\0';
11380Sstevel@tonic-gate } while (--c);
11390Sstevel@tonic-gate ibc = ibs;
11400Sstevel@tonic-gate }
11410Sstevel@tonic-gate }
11420Sstevel@tonic-gate
11430Sstevel@tonic-gate /* Swap the bytes in the input buffer if necessary */
11440Sstevel@tonic-gate
11450Sstevel@tonic-gate if (cflag&SWAB)
11460Sstevel@tonic-gate {
11470Sstevel@tonic-gate ip = ibuf;
11480Sstevel@tonic-gate if (ibc & 1) /* if the byte count is odd, */
11490Sstevel@tonic-gate {
11500Sstevel@tonic-gate ip[ibc] = 0; /* make it even, pad with zero */
11510Sstevel@tonic-gate }
11520Sstevel@tonic-gate c = ibc >> 1; /* compute the pair count */
11530Sstevel@tonic-gate do {
11540Sstevel@tonic-gate ic = *ip++;
11550Sstevel@tonic-gate ip[-1] = *ip;
11560Sstevel@tonic-gate *ip++ = ic;
11570Sstevel@tonic-gate } while (--c); /* do two bytes at a time */
11580Sstevel@tonic-gate }
11590Sstevel@tonic-gate
11600Sstevel@tonic-gate /* Select the appropriate conversion loop */
11610Sstevel@tonic-gate
11620Sstevel@tonic-gate ip = ibuf;
11630Sstevel@tonic-gate switch (conv)
11640Sstevel@tonic-gate {
11650Sstevel@tonic-gate
11660Sstevel@tonic-gate /* Simple copy: no conversion, preserve the input block size */
11670Sstevel@tonic-gate
11680Sstevel@tonic-gate case COPY:
11690Sstevel@tonic-gate obc = ibc;
11700Sstevel@tonic-gate (void) flsh();
11710Sstevel@tonic-gate break;
11720Sstevel@tonic-gate
11730Sstevel@tonic-gate /* Simple copy: pack all output into equal sized blocks */
11740Sstevel@tonic-gate
11750Sstevel@tonic-gate case REBLOCK:
11760Sstevel@tonic-gate case LCREBLOCK:
11770Sstevel@tonic-gate case UCREBLOCK:
11780Sstevel@tonic-gate case NBASCII:
11790Sstevel@tonic-gate case LCNBASCII:
11800Sstevel@tonic-gate case UCNBASCII:
11810Sstevel@tonic-gate case NBEBCDIC:
11820Sstevel@tonic-gate case LCNBEBCDIC:
11830Sstevel@tonic-gate case UCNBEBCDIC:
11840Sstevel@tonic-gate case NBIBM:
11850Sstevel@tonic-gate case LCNBIBM:
11860Sstevel@tonic-gate case UCNBIBM:
11870Sstevel@tonic-gate while ((c = ibc) != 0)
11880Sstevel@tonic-gate {
11890Sstevel@tonic-gate if (c > (obs - obc))
11900Sstevel@tonic-gate {
11910Sstevel@tonic-gate c = obs - obc;
11920Sstevel@tonic-gate }
11930Sstevel@tonic-gate ibc -= c;
11940Sstevel@tonic-gate obc += c;
11950Sstevel@tonic-gate switch (conv)
11960Sstevel@tonic-gate {
11970Sstevel@tonic-gate case REBLOCK:
11980Sstevel@tonic-gate do {
11990Sstevel@tonic-gate *op++ = *ip++;
12000Sstevel@tonic-gate } while (--c);
12010Sstevel@tonic-gate break;
12020Sstevel@tonic-gate
12030Sstevel@tonic-gate case LCREBLOCK:
12040Sstevel@tonic-gate do {
12050Sstevel@tonic-gate *op++ = utol[*ip++];
12060Sstevel@tonic-gate } while (--c);
12070Sstevel@tonic-gate break;
12080Sstevel@tonic-gate
12090Sstevel@tonic-gate case UCREBLOCK:
12100Sstevel@tonic-gate do {
12110Sstevel@tonic-gate *op++ = ltou[*ip++];
12120Sstevel@tonic-gate } while (--c);
12130Sstevel@tonic-gate break;
12140Sstevel@tonic-gate
12150Sstevel@tonic-gate case NBASCII:
12160Sstevel@tonic-gate do {
12170Sstevel@tonic-gate *op++ = etoa[*ip++];
12180Sstevel@tonic-gate } while (--c);
12190Sstevel@tonic-gate break;
12200Sstevel@tonic-gate
12210Sstevel@tonic-gate case LCNBASCII:
12220Sstevel@tonic-gate do {
12230Sstevel@tonic-gate *op++ = utol[etoa[*ip++]];
12240Sstevel@tonic-gate } while (--c);
12250Sstevel@tonic-gate break;
12260Sstevel@tonic-gate
12270Sstevel@tonic-gate case UCNBASCII:
12280Sstevel@tonic-gate do {
12290Sstevel@tonic-gate *op++ = ltou[etoa[*ip++]];
12300Sstevel@tonic-gate } while (--c);
12310Sstevel@tonic-gate break;
12320Sstevel@tonic-gate
12330Sstevel@tonic-gate case NBEBCDIC:
12340Sstevel@tonic-gate do {
12350Sstevel@tonic-gate *op++ = atoe[*ip++];
12360Sstevel@tonic-gate } while (--c);
12370Sstevel@tonic-gate break;
12380Sstevel@tonic-gate
12390Sstevel@tonic-gate case LCNBEBCDIC:
12400Sstevel@tonic-gate do {
12410Sstevel@tonic-gate *op++ = atoe[utol[*ip++]];
12420Sstevel@tonic-gate } while (--c);
12430Sstevel@tonic-gate break;
12440Sstevel@tonic-gate
12450Sstevel@tonic-gate case UCNBEBCDIC:
12460Sstevel@tonic-gate do {
12470Sstevel@tonic-gate *op++ = atoe[ltou[*ip++]];
12480Sstevel@tonic-gate } while (--c);
12490Sstevel@tonic-gate break;
12500Sstevel@tonic-gate
12510Sstevel@tonic-gate case NBIBM:
12520Sstevel@tonic-gate do {
12530Sstevel@tonic-gate *op++ = atoibm[*ip++];
12540Sstevel@tonic-gate } while (--c);
12550Sstevel@tonic-gate break;
12560Sstevel@tonic-gate
12570Sstevel@tonic-gate case LCNBIBM:
12580Sstevel@tonic-gate do {
12590Sstevel@tonic-gate *op++ = atoibm[utol[*ip++]];
12600Sstevel@tonic-gate } while (--c);
12610Sstevel@tonic-gate break;
12620Sstevel@tonic-gate
12630Sstevel@tonic-gate case UCNBIBM:
12640Sstevel@tonic-gate do {
12650Sstevel@tonic-gate *op++ = atoibm[ltou[*ip++]];
12660Sstevel@tonic-gate } while (--c);
12670Sstevel@tonic-gate break;
12680Sstevel@tonic-gate }
12690Sstevel@tonic-gate if (obc >= obs)
12700Sstevel@tonic-gate {
12710Sstevel@tonic-gate op = flsh();
12720Sstevel@tonic-gate }
12730Sstevel@tonic-gate }
12740Sstevel@tonic-gate break;
12750Sstevel@tonic-gate
12760Sstevel@tonic-gate /* Convert from blocked records to lines terminated by newline */
12770Sstevel@tonic-gate
12780Sstevel@tonic-gate case UNBLOCK:
12790Sstevel@tonic-gate case LCUNBLOCK:
12800Sstevel@tonic-gate case UCUNBLOCK:
12810Sstevel@tonic-gate case ASCII:
12820Sstevel@tonic-gate case LCASCII:
12830Sstevel@tonic-gate case UCASCII:
12840Sstevel@tonic-gate while ((c = ibc) != 0)
12850Sstevel@tonic-gate {
12860Sstevel@tonic-gate if (c > (cbs - cbc))
12870Sstevel@tonic-gate /* if more than one record, */
12880Sstevel@tonic-gate {
12890Sstevel@tonic-gate c = cbs - cbc;
12900Sstevel@tonic-gate /* only copy one record */
12910Sstevel@tonic-gate }
12920Sstevel@tonic-gate ibc -= c;
12930Sstevel@tonic-gate cbc += c;
12940Sstevel@tonic-gate obc += c;
12950Sstevel@tonic-gate switch (conv)
12960Sstevel@tonic-gate {
12970Sstevel@tonic-gate case UNBLOCK:
12980Sstevel@tonic-gate do {
12990Sstevel@tonic-gate *op++ = *ip++;
13000Sstevel@tonic-gate } while (--c);
13010Sstevel@tonic-gate break;
13020Sstevel@tonic-gate
13030Sstevel@tonic-gate case LCUNBLOCK:
13040Sstevel@tonic-gate do {
13050Sstevel@tonic-gate *op++ = utol[*ip++];
13060Sstevel@tonic-gate } while (--c);
13070Sstevel@tonic-gate break;
13080Sstevel@tonic-gate
13090Sstevel@tonic-gate case UCUNBLOCK:
13100Sstevel@tonic-gate do {
13110Sstevel@tonic-gate *op++ = ltou[*ip++];
13120Sstevel@tonic-gate } while (--c);
13130Sstevel@tonic-gate break;
13140Sstevel@tonic-gate
13150Sstevel@tonic-gate case ASCII:
13160Sstevel@tonic-gate do {
13170Sstevel@tonic-gate *op++ = etoa[*ip++];
13180Sstevel@tonic-gate } while (--c);
13190Sstevel@tonic-gate break;
13200Sstevel@tonic-gate
13210Sstevel@tonic-gate case LCASCII:
13220Sstevel@tonic-gate do {
13230Sstevel@tonic-gate *op++ = utol[etoa[*ip++]];
13240Sstevel@tonic-gate } while (--c);
13250Sstevel@tonic-gate break;
13260Sstevel@tonic-gate
13270Sstevel@tonic-gate case UCASCII:
13280Sstevel@tonic-gate do {
13290Sstevel@tonic-gate *op++ = ltou[etoa[*ip++]];
13300Sstevel@tonic-gate } while (--c);
13310Sstevel@tonic-gate break;
13320Sstevel@tonic-gate }
13330Sstevel@tonic-gate
13340Sstevel@tonic-gate /* Trim trailing blanks if the line is full */
13350Sstevel@tonic-gate
13360Sstevel@tonic-gate if (cbc == cbs)
13370Sstevel@tonic-gate {
13380Sstevel@tonic-gate c = cbs; /* `do - while' is usually */
13390Sstevel@tonic-gate do { /* faster than `for' */
13400Sstevel@tonic-gate if ((*--op) != ' ')
13410Sstevel@tonic-gate {
13420Sstevel@tonic-gate op++;
13430Sstevel@tonic-gate break;
13440Sstevel@tonic-gate }
13450Sstevel@tonic-gate } while (--c);
13460Sstevel@tonic-gate *op++ = '\n';
13470Sstevel@tonic-gate obc -= cbs - c - 1;
13480Sstevel@tonic-gate cbc = 0;
13490Sstevel@tonic-gate
13500Sstevel@tonic-gate /* Flush the output buffer if full */
13510Sstevel@tonic-gate
13520Sstevel@tonic-gate while (obc >= obs)
13530Sstevel@tonic-gate {
13540Sstevel@tonic-gate op = flsh();
13550Sstevel@tonic-gate }
13560Sstevel@tonic-gate }
13570Sstevel@tonic-gate }
13580Sstevel@tonic-gate break;
13590Sstevel@tonic-gate
13600Sstevel@tonic-gate /* Convert to blocked records */
13610Sstevel@tonic-gate
13620Sstevel@tonic-gate case BLOCK:
13630Sstevel@tonic-gate case LCBLOCK:
13640Sstevel@tonic-gate case UCBLOCK:
13650Sstevel@tonic-gate case EBCDIC:
13660Sstevel@tonic-gate case LCEBCDIC:
13670Sstevel@tonic-gate case UCEBCDIC:
13680Sstevel@tonic-gate case IBM:
13690Sstevel@tonic-gate case LCIBM:
13700Sstevel@tonic-gate case UCIBM:
13710Sstevel@tonic-gate while ((c = ibc) != 0)
13720Sstevel@tonic-gate {
13730Sstevel@tonic-gate int nlflag = 0;
13740Sstevel@tonic-gate
13750Sstevel@tonic-gate /* We may have to skip to the end of a long line */
13760Sstevel@tonic-gate
13770Sstevel@tonic-gate if (skipf)
13780Sstevel@tonic-gate {
13790Sstevel@tonic-gate do {
13800Sstevel@tonic-gate if ((ic = *ip++) == '\n')
13810Sstevel@tonic-gate {
13820Sstevel@tonic-gate skipf = 0;
13830Sstevel@tonic-gate c--;
13840Sstevel@tonic-gate break;
13850Sstevel@tonic-gate }
13860Sstevel@tonic-gate } while (--c);
13870Sstevel@tonic-gate if ((ibc = c) == 0)
13880Sstevel@tonic-gate {
13890Sstevel@tonic-gate continue;
13900Sstevel@tonic-gate /* read another block */
13910Sstevel@tonic-gate }
13920Sstevel@tonic-gate }
13930Sstevel@tonic-gate
13940Sstevel@tonic-gate /* If anything left, copy until newline */
13950Sstevel@tonic-gate
13960Sstevel@tonic-gate if (c > (cbs - cbc + 1))
13970Sstevel@tonic-gate {
13980Sstevel@tonic-gate c = cbs - cbc + 1;
13990Sstevel@tonic-gate }
14000Sstevel@tonic-gate ibc -= c;
14010Sstevel@tonic-gate cbc += c;
14020Sstevel@tonic-gate obc += c;
14030Sstevel@tonic-gate
14040Sstevel@tonic-gate switch (conv)
14050Sstevel@tonic-gate {
14060Sstevel@tonic-gate case BLOCK:
14070Sstevel@tonic-gate do {
14080Sstevel@tonic-gate if ((ic = *ip++) != '\n')
14090Sstevel@tonic-gate {
14100Sstevel@tonic-gate *op++ = ic;
14110Sstevel@tonic-gate }
14120Sstevel@tonic-gate else
14130Sstevel@tonic-gate {
14140Sstevel@tonic-gate nlflag = 1;
14150Sstevel@tonic-gate break;
14160Sstevel@tonic-gate }
14170Sstevel@tonic-gate } while (--c);
14180Sstevel@tonic-gate break;
14190Sstevel@tonic-gate
14200Sstevel@tonic-gate case LCBLOCK:
14210Sstevel@tonic-gate do {
14220Sstevel@tonic-gate if ((ic = *ip++) != '\n')
14230Sstevel@tonic-gate {
14240Sstevel@tonic-gate *op++ = utol[ic];
14250Sstevel@tonic-gate }
14260Sstevel@tonic-gate else
14270Sstevel@tonic-gate {
14280Sstevel@tonic-gate nlflag = 1;
14290Sstevel@tonic-gate break;
14300Sstevel@tonic-gate }
14310Sstevel@tonic-gate } while (--c);
14320Sstevel@tonic-gate break;
14330Sstevel@tonic-gate
14340Sstevel@tonic-gate case UCBLOCK:
14350Sstevel@tonic-gate do {
14360Sstevel@tonic-gate if ((ic = *ip++) != '\n')
14370Sstevel@tonic-gate {
14380Sstevel@tonic-gate *op++ = ltou[ic];
14390Sstevel@tonic-gate }
14400Sstevel@tonic-gate else
14410Sstevel@tonic-gate {
14420Sstevel@tonic-gate nlflag = 1;
14430Sstevel@tonic-gate break;
14440Sstevel@tonic-gate }
14450Sstevel@tonic-gate } while (--c);
14460Sstevel@tonic-gate break;
14470Sstevel@tonic-gate
14480Sstevel@tonic-gate case EBCDIC:
14490Sstevel@tonic-gate do {
14500Sstevel@tonic-gate if ((ic = *ip++) != '\n')
14510Sstevel@tonic-gate {
14520Sstevel@tonic-gate *op++ = atoe[ic];
14530Sstevel@tonic-gate }
14540Sstevel@tonic-gate else
14550Sstevel@tonic-gate {
14560Sstevel@tonic-gate nlflag = 1;
14570Sstevel@tonic-gate break;
14580Sstevel@tonic-gate }
14590Sstevel@tonic-gate } while (--c);
14600Sstevel@tonic-gate break;
14610Sstevel@tonic-gate
14620Sstevel@tonic-gate case LCEBCDIC:
14630Sstevel@tonic-gate do {
14640Sstevel@tonic-gate if ((ic = *ip++) != '\n')
14650Sstevel@tonic-gate {
14660Sstevel@tonic-gate *op++ = atoe[utol[ic]];
14670Sstevel@tonic-gate }
14680Sstevel@tonic-gate else
14690Sstevel@tonic-gate {
14700Sstevel@tonic-gate nlflag = 1;
14710Sstevel@tonic-gate break;
14720Sstevel@tonic-gate }
14730Sstevel@tonic-gate } while (--c);
14740Sstevel@tonic-gate break;
14750Sstevel@tonic-gate
14760Sstevel@tonic-gate case UCEBCDIC:
14770Sstevel@tonic-gate do {
14780Sstevel@tonic-gate if ((ic = *ip++) != '\n')
14790Sstevel@tonic-gate {
14800Sstevel@tonic-gate *op++ = atoe[ltou[ic]];
14810Sstevel@tonic-gate }
14820Sstevel@tonic-gate else
14830Sstevel@tonic-gate {
14840Sstevel@tonic-gate nlflag = 1;
14850Sstevel@tonic-gate break;
14860Sstevel@tonic-gate }
14870Sstevel@tonic-gate } while (--c);
14880Sstevel@tonic-gate break;
14890Sstevel@tonic-gate
14900Sstevel@tonic-gate case IBM:
14910Sstevel@tonic-gate do {
14920Sstevel@tonic-gate if ((ic = *ip++) != '\n')
14930Sstevel@tonic-gate {
14940Sstevel@tonic-gate *op++ = atoibm[ic];
14950Sstevel@tonic-gate }
14960Sstevel@tonic-gate else
14970Sstevel@tonic-gate {
14980Sstevel@tonic-gate nlflag = 1;
14990Sstevel@tonic-gate break;
15000Sstevel@tonic-gate }
15010Sstevel@tonic-gate } while (--c);
15020Sstevel@tonic-gate break;
15030Sstevel@tonic-gate
15040Sstevel@tonic-gate case LCIBM:
15050Sstevel@tonic-gate do {
15060Sstevel@tonic-gate if ((ic = *ip++) != '\n')
15070Sstevel@tonic-gate {
15080Sstevel@tonic-gate *op++ = atoibm[utol[ic]];
15090Sstevel@tonic-gate }
15100Sstevel@tonic-gate else
15110Sstevel@tonic-gate {
15120Sstevel@tonic-gate nlflag = 1;
15130Sstevel@tonic-gate break;
15140Sstevel@tonic-gate }
15150Sstevel@tonic-gate } while (--c);
15160Sstevel@tonic-gate break;
15170Sstevel@tonic-gate
15180Sstevel@tonic-gate case UCIBM:
15190Sstevel@tonic-gate do {
15200Sstevel@tonic-gate if ((ic = *ip++) != '\n')
15210Sstevel@tonic-gate {
15220Sstevel@tonic-gate *op++ = atoibm[ltou[ic]];
15230Sstevel@tonic-gate }
15240Sstevel@tonic-gate else
15250Sstevel@tonic-gate {
15260Sstevel@tonic-gate nlflag = 1;
15270Sstevel@tonic-gate break;
15280Sstevel@tonic-gate }
15290Sstevel@tonic-gate } while (--c);
15300Sstevel@tonic-gate break;
15310Sstevel@tonic-gate }
15320Sstevel@tonic-gate
15330Sstevel@tonic-gate /* If newline found, update all the counters and */
15340Sstevel@tonic-gate /* pointers, pad with trailing blanks if necessary */
15350Sstevel@tonic-gate
15360Sstevel@tonic-gate if (nlflag)
15370Sstevel@tonic-gate {
15380Sstevel@tonic-gate ibc += c - 1;
15390Sstevel@tonic-gate obc += cbs - cbc;
15400Sstevel@tonic-gate c += cbs - cbc;
15410Sstevel@tonic-gate cbc = 0;
15420Sstevel@tonic-gate if (c > 0)
15430Sstevel@tonic-gate {
15440Sstevel@tonic-gate /* Use the right kind of blank */
15450Sstevel@tonic-gate
15460Sstevel@tonic-gate switch (conv)
15470Sstevel@tonic-gate {
15480Sstevel@tonic-gate case BLOCK:
15490Sstevel@tonic-gate case LCBLOCK:
15500Sstevel@tonic-gate case UCBLOCK:
15510Sstevel@tonic-gate ic = ' ';
15520Sstevel@tonic-gate break;
15530Sstevel@tonic-gate
15540Sstevel@tonic-gate case EBCDIC:
15550Sstevel@tonic-gate case LCEBCDIC:
15560Sstevel@tonic-gate case UCEBCDIC:
15570Sstevel@tonic-gate ic = atoe[' '];
15580Sstevel@tonic-gate break;
15590Sstevel@tonic-gate
15600Sstevel@tonic-gate case IBM:
15610Sstevel@tonic-gate case LCIBM:
15620Sstevel@tonic-gate case UCIBM:
15630Sstevel@tonic-gate ic = atoibm[' '];
15640Sstevel@tonic-gate break;
15650Sstevel@tonic-gate }
15660Sstevel@tonic-gate
15670Sstevel@tonic-gate /* Pad with trailing blanks */
15680Sstevel@tonic-gate
15690Sstevel@tonic-gate do {
15700Sstevel@tonic-gate *op++ = ic;
15710Sstevel@tonic-gate } while (--c);
15720Sstevel@tonic-gate }
15730Sstevel@tonic-gate }
15740Sstevel@tonic-gate
15750Sstevel@tonic-gate /* If not end of line, this line may be too long */
15760Sstevel@tonic-gate
15770Sstevel@tonic-gate else if (cbc > cbs)
15780Sstevel@tonic-gate {
15790Sstevel@tonic-gate skipf = 1; /* note skip in progress */
15800Sstevel@tonic-gate obc--;
15810Sstevel@tonic-gate op--;
15820Sstevel@tonic-gate cbc = 0;
15830Sstevel@tonic-gate ntrunc++; /* count another long line */
15840Sstevel@tonic-gate }
15850Sstevel@tonic-gate
15860Sstevel@tonic-gate /* Flush the output buffer if full */
15870Sstevel@tonic-gate
15880Sstevel@tonic-gate while (obc >= obs)
15890Sstevel@tonic-gate {
15900Sstevel@tonic-gate op = flsh();
15910Sstevel@tonic-gate }
15920Sstevel@tonic-gate }
15930Sstevel@tonic-gate break;
15940Sstevel@tonic-gate }
15950Sstevel@tonic-gate }
1596*212Scf46844 /* NOTREACHED */
1597*212Scf46844 return (0);
15980Sstevel@tonic-gate }
15990Sstevel@tonic-gate
16000Sstevel@tonic-gate /* match ************************************************************** */
16010Sstevel@tonic-gate /* */
16020Sstevel@tonic-gate /* Compare two text strings for equality */
16030Sstevel@tonic-gate /* */
16040Sstevel@tonic-gate /* Arg: s - pointer to string to match with a command arg */
16050Sstevel@tonic-gate /* Global arg: string - pointer to command arg */
16060Sstevel@tonic-gate /* */
16070Sstevel@tonic-gate /* Return: 1 if match, 0 if no match */
16080Sstevel@tonic-gate /* If match, also reset `string' to point to the text */
16090Sstevel@tonic-gate /* that follows the matching text. */
16100Sstevel@tonic-gate /* */
16110Sstevel@tonic-gate /* ******************************************************************** */
16120Sstevel@tonic-gate
16130Sstevel@tonic-gate static int
match(s)16140Sstevel@tonic-gate match(s)
16150Sstevel@tonic-gate char *s;
16160Sstevel@tonic-gate {
16170Sstevel@tonic-gate char *cs;
16180Sstevel@tonic-gate
16190Sstevel@tonic-gate cs = string;
16200Sstevel@tonic-gate while (*cs++ == *s)
16210Sstevel@tonic-gate {
16220Sstevel@tonic-gate if (*s++ == '\0')
16230Sstevel@tonic-gate {
16240Sstevel@tonic-gate goto true;
16250Sstevel@tonic-gate }
16260Sstevel@tonic-gate }
16270Sstevel@tonic-gate if (*s != '\0')
16280Sstevel@tonic-gate {
16290Sstevel@tonic-gate return (0);
16300Sstevel@tonic-gate }
16310Sstevel@tonic-gate
16320Sstevel@tonic-gate true:
16330Sstevel@tonic-gate cs--;
16340Sstevel@tonic-gate string = cs;
16350Sstevel@tonic-gate return (1);
16360Sstevel@tonic-gate }
16370Sstevel@tonic-gate
16380Sstevel@tonic-gate /* number ************************************************************* */
16390Sstevel@tonic-gate /* */
16400Sstevel@tonic-gate /* Convert a numeric arg to binary */
16410Sstevel@tonic-gate /* */
16420Sstevel@tonic-gate /* Arg: big - maximum valid input number */
16430Sstevel@tonic-gate /* Global arg: string - pointer to command arg */
16440Sstevel@tonic-gate /* */
16450Sstevel@tonic-gate /* Valid forms: 123 | 123k | 123w | 123b | 123*123 | 123x123 */
16460Sstevel@tonic-gate /* plus combinations such as 2b*3kw*4w */
16470Sstevel@tonic-gate /* */
16480Sstevel@tonic-gate /* Return: converted number */
16490Sstevel@tonic-gate /* */
16500Sstevel@tonic-gate /* ******************************************************************** */
16510Sstevel@tonic-gate
16520Sstevel@tonic-gate static unsigned long long
number(big)16530Sstevel@tonic-gate number(big)
16540Sstevel@tonic-gate long long big;
16550Sstevel@tonic-gate {
16560Sstevel@tonic-gate char *cs;
16570Sstevel@tonic-gate long long n;
16580Sstevel@tonic-gate long long cut = BIG / 10; /* limit to avoid overflow */
16590Sstevel@tonic-gate
16600Sstevel@tonic-gate cs = string;
16610Sstevel@tonic-gate n = 0;
16620Sstevel@tonic-gate while ((*cs >= '0') && (*cs <= '9') && (n <= cut))
16630Sstevel@tonic-gate {
16640Sstevel@tonic-gate n = n*10 + *cs++ - '0';
16650Sstevel@tonic-gate }
16660Sstevel@tonic-gate for (;;)
16670Sstevel@tonic-gate {
16680Sstevel@tonic-gate switch (*cs++)
16690Sstevel@tonic-gate {
16700Sstevel@tonic-gate
16710Sstevel@tonic-gate case 'k':
16720Sstevel@tonic-gate n *= 1024;
16730Sstevel@tonic-gate continue;
16740Sstevel@tonic-gate
16750Sstevel@tonic-gate case 'w':
16760Sstevel@tonic-gate n *= 2;
16770Sstevel@tonic-gate continue;
16780Sstevel@tonic-gate
16790Sstevel@tonic-gate case 'b':
16800Sstevel@tonic-gate n *= BSIZE;
16810Sstevel@tonic-gate continue;
16820Sstevel@tonic-gate
16830Sstevel@tonic-gate case '*':
16840Sstevel@tonic-gate case 'x':
16850Sstevel@tonic-gate string = cs;
16860Sstevel@tonic-gate n *= number(BIG);
16870Sstevel@tonic-gate
16880Sstevel@tonic-gate /* FALLTHROUGH */
16890Sstevel@tonic-gate /* Fall into exit test, recursion has read rest of string */
16900Sstevel@tonic-gate /* End of string, check for a valid number */
16910Sstevel@tonic-gate
16920Sstevel@tonic-gate case '\0':
16930Sstevel@tonic-gate if ((n > big) || (n < 0))
16940Sstevel@tonic-gate {
16950Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s \"%llu\"\n",
16960Sstevel@tonic-gate gettext("argument out of range:"), n);
16970Sstevel@tonic-gate exit(2);
16980Sstevel@tonic-gate }
16990Sstevel@tonic-gate return (n);
17000Sstevel@tonic-gate
17010Sstevel@tonic-gate default:
17020Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s \"%s\"\n",
17030Sstevel@tonic-gate gettext("bad numeric argument:"), string);
17040Sstevel@tonic-gate exit(2);
17050Sstevel@tonic-gate }
17060Sstevel@tonic-gate } /* never gets here */
17070Sstevel@tonic-gate }
17080Sstevel@tonic-gate
17090Sstevel@tonic-gate /* flsh *************************************************************** */
17100Sstevel@tonic-gate /* */
17110Sstevel@tonic-gate /* Flush the output buffer, move any excess bytes down to the beginning */
17120Sstevel@tonic-gate /* */
17130Sstevel@tonic-gate /* Arg: none */
17140Sstevel@tonic-gate /* Global args: obuf, obc, obs, nofr, nopr */
17150Sstevel@tonic-gate /* */
17160Sstevel@tonic-gate /* Return: Pointer to the first free byte in the output buffer. */
17170Sstevel@tonic-gate /* Also reset `obc' to account for moved bytes. */
17180Sstevel@tonic-gate /* */
17190Sstevel@tonic-gate /* ******************************************************************** */
17200Sstevel@tonic-gate
17210Sstevel@tonic-gate static unsigned char
flsh()17220Sstevel@tonic-gate *flsh()
17230Sstevel@tonic-gate {
17240Sstevel@tonic-gate unsigned char *op, *cp;
17250Sstevel@tonic-gate int bc;
17260Sstevel@tonic-gate unsigned int oc;
17270Sstevel@tonic-gate
17280Sstevel@tonic-gate if (obc) /* don't flush if the buffer is empty */
17290Sstevel@tonic-gate {
17300Sstevel@tonic-gate if (obc >= obs) {
17310Sstevel@tonic-gate oc = obs;
17320Sstevel@tonic-gate nofr++; /* count a full output buffer */
17330Sstevel@tonic-gate }
17340Sstevel@tonic-gate else
17350Sstevel@tonic-gate {
17360Sstevel@tonic-gate oc = obc;
17370Sstevel@tonic-gate nopr++; /* count a partial output buffer */
17380Sstevel@tonic-gate }
17390Sstevel@tonic-gate bc = write(obf, (char *)obuf, oc);
17400Sstevel@tonic-gate if (bc != oc) {
17410Sstevel@tonic-gate if (bc < 0)
17420Sstevel@tonic-gate perror("write");
17430Sstevel@tonic-gate else
17440Sstevel@tonic-gate (void) fprintf(stderr,
17450Sstevel@tonic-gate gettext("dd: unexpected short write, "
17460Sstevel@tonic-gate "wrote %d bytes, expected %d\n"), bc, oc);
17470Sstevel@tonic-gate term(2);
17480Sstevel@tonic-gate }
17490Sstevel@tonic-gate obc -= oc;
17500Sstevel@tonic-gate op = obuf;
17510Sstevel@tonic-gate
17520Sstevel@tonic-gate /* If any data in the conversion buffer, move it into */
17530Sstevel@tonic-gate /* the output buffer */
17540Sstevel@tonic-gate
17550Sstevel@tonic-gate if (obc) {
17560Sstevel@tonic-gate cp = obuf + obs;
17570Sstevel@tonic-gate bc = obc;
17580Sstevel@tonic-gate do {
17590Sstevel@tonic-gate *op++ = *cp++;
17600Sstevel@tonic-gate } while (--bc);
17610Sstevel@tonic-gate }
17620Sstevel@tonic-gate return (op);
17630Sstevel@tonic-gate }
17640Sstevel@tonic-gate return (obuf);
17650Sstevel@tonic-gate }
17660Sstevel@tonic-gate
17670Sstevel@tonic-gate /* term *************************************************************** */
17680Sstevel@tonic-gate /* */
17690Sstevel@tonic-gate /* Write record statistics, then exit */
17700Sstevel@tonic-gate /* */
17710Sstevel@tonic-gate /* Arg: c - exit status code */
17720Sstevel@tonic-gate /* */
17730Sstevel@tonic-gate /* Return: no return, calls exit */
17740Sstevel@tonic-gate /* */
17750Sstevel@tonic-gate /* ******************************************************************** */
17760Sstevel@tonic-gate
17770Sstevel@tonic-gate static void
term(c)17780Sstevel@tonic-gate term(c)
17790Sstevel@tonic-gate int c;
17800Sstevel@tonic-gate {
17810Sstevel@tonic-gate stats();
17820Sstevel@tonic-gate exit(c);
17830Sstevel@tonic-gate }
17840Sstevel@tonic-gate
17850Sstevel@tonic-gate /* stats ************************************************************** */
17860Sstevel@tonic-gate /* */
17870Sstevel@tonic-gate /* Write record statistics onto standard error */
17880Sstevel@tonic-gate /* */
17890Sstevel@tonic-gate /* Args: none */
17900Sstevel@tonic-gate /* Global args: nifr, nipr, nofr, nopr, ntrunc */
17910Sstevel@tonic-gate /* */
17920Sstevel@tonic-gate /* Return: void */
17930Sstevel@tonic-gate /* */
17940Sstevel@tonic-gate /* ******************************************************************** */
17950Sstevel@tonic-gate
17960Sstevel@tonic-gate static void
stats()17970Sstevel@tonic-gate stats()
17980Sstevel@tonic-gate {
17990Sstevel@tonic-gate (void) fprintf(stderr, gettext("%llu+%llu records in\n"), nifr, nipr);
18000Sstevel@tonic-gate (void) fprintf(stderr, gettext("%llu+%llu records out\n"), nofr, nopr);
18010Sstevel@tonic-gate if (ntrunc) {
18020Sstevel@tonic-gate (void) fprintf(stderr,
18030Sstevel@tonic-gate gettext("%llu truncated record(s)\n"), ntrunc);
18040Sstevel@tonic-gate }
18050Sstevel@tonic-gate }
1806