17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
77c478bd9Sstevel@tonic-gate * with the License.
87c478bd9Sstevel@tonic-gate *
97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
127c478bd9Sstevel@tonic-gate * and limitations under the License.
137c478bd9Sstevel@tonic-gate *
147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
197c478bd9Sstevel@tonic-gate *
207c478bd9Sstevel@tonic-gate * CDDL HEADER END
217c478bd9Sstevel@tonic-gate */
227c478bd9Sstevel@tonic-gate
237c478bd9Sstevel@tonic-gate /*
24a77d64afScf46844 * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
257c478bd9Sstevel@tonic-gate * Use is subject to license terms.
264cddff70SJosef 'Jeff' Sipek * Copyright 2012, Josef 'Jeff' Sipek <jeffpc@31bits.net>. All rights reserved.
2719d32b9aSRobert Mustacchi * Copyright (c) 2014, Joyent, Inc. All rights reserved.
2861304e4fSPaul Dagnelie * Copyright (c) 2014 by Delphix. All rights reserved.
29*c53c97f7SRobert Mustacchi * Copyright 2021 Oxide Computer Company
307c478bd9Sstevel@tonic-gate */
317c478bd9Sstevel@tonic-gate
32a77d64afScf46844 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
33a77d64afScf46844 /* All Rights Reserved */
34a77d64afScf46844
357c478bd9Sstevel@tonic-gate /*
367c478bd9Sstevel@tonic-gate * convert and copy
377c478bd9Sstevel@tonic-gate */
387c478bd9Sstevel@tonic-gate
397c478bd9Sstevel@tonic-gate #include <stdio.h>
407c478bd9Sstevel@tonic-gate #include <signal.h>
417c478bd9Sstevel@tonic-gate #include <fcntl.h>
427c478bd9Sstevel@tonic-gate #include <sys/param.h>
437c478bd9Sstevel@tonic-gate #include <sys/types.h>
447c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
457c478bd9Sstevel@tonic-gate #include <sys/stat.h>
467c478bd9Sstevel@tonic-gate #include <unistd.h>
477c478bd9Sstevel@tonic-gate #include <stdlib.h>
487c478bd9Sstevel@tonic-gate #include <locale.h>
497c478bd9Sstevel@tonic-gate #include <string.h>
5019d32b9aSRobert Mustacchi #include <sys/time.h>
5119d32b9aSRobert Mustacchi #include <errno.h>
5219d32b9aSRobert Mustacchi #include <strings.h>
53b928ac84SToomas Soome #include <libcmdutils.h>
547c478bd9Sstevel@tonic-gate
557c478bd9Sstevel@tonic-gate /* The BIG parameter is machine dependent. It should be a long integer */
567c478bd9Sstevel@tonic-gate /* constant that can be used by the number parser to check the validity */
577c478bd9Sstevel@tonic-gate /* of numeric parameters. On 16-bit machines, it should probably be */
587c478bd9Sstevel@tonic-gate /* the maximum unsigned integer, 0177777L. On 32-bit machines where */
597c478bd9Sstevel@tonic-gate /* longs are the same size as ints, the maximum signed integer is more */
607c478bd9Sstevel@tonic-gate /* appropriate. This value is 017777777777L. In 64 bit environments, */
617c478bd9Sstevel@tonic-gate /* the maximum signed integer value is 0777777777777777777777LL */
627c478bd9Sstevel@tonic-gate
637c478bd9Sstevel@tonic-gate #define BIG 0777777777777777777777LL
647c478bd9Sstevel@tonic-gate
657c478bd9Sstevel@tonic-gate #define BSIZE 512
667c478bd9Sstevel@tonic-gate
677c478bd9Sstevel@tonic-gate /* Option parameters */
687c478bd9Sstevel@tonic-gate
697c478bd9Sstevel@tonic-gate #define COPY 0 /* file copy, preserve input block size */
707c478bd9Sstevel@tonic-gate #define REBLOCK 1 /* file copy, change block size */
717c478bd9Sstevel@tonic-gate #define LCREBLOCK 2 /* file copy, convert to lower case */
727c478bd9Sstevel@tonic-gate #define UCREBLOCK 3 /* file copy, convert to upper case */
737c478bd9Sstevel@tonic-gate #define NBASCII 4 /* file copy, convert from EBCDIC to ASCII */
747c478bd9Sstevel@tonic-gate #define LCNBASCII 5 /* file copy, EBCDIC to lower case ASCII */
757c478bd9Sstevel@tonic-gate #define UCNBASCII 6 /* file copy, EBCDIC to upper case ASCII */
767c478bd9Sstevel@tonic-gate #define NBEBCDIC 7 /* file copy, convert from ASCII to EBCDIC */
777c478bd9Sstevel@tonic-gate #define LCNBEBCDIC 8 /* file copy, ASCII to lower case EBCDIC */
787c478bd9Sstevel@tonic-gate #define UCNBEBCDIC 9 /* file copy, ASCII to upper case EBCDIC */
797c478bd9Sstevel@tonic-gate #define NBIBM 10 /* file copy, convert from ASCII to IBM */
807c478bd9Sstevel@tonic-gate #define LCNBIBM 11 /* file copy, ASCII to lower case IBM */
817c478bd9Sstevel@tonic-gate #define UCNBIBM 12 /* file copy, ASCII to upper case IBM */
827c478bd9Sstevel@tonic-gate #define UNBLOCK 13 /* convert blocked ASCII to ASCII */
837c478bd9Sstevel@tonic-gate #define LCUNBLOCK 14 /* convert blocked ASCII to lower case ASCII */
847c478bd9Sstevel@tonic-gate #define UCUNBLOCK 15 /* convert blocked ASCII to upper case ASCII */
857c478bd9Sstevel@tonic-gate #define ASCII 16 /* convert blocked EBCDIC to ASCII */
867c478bd9Sstevel@tonic-gate #define LCASCII 17 /* convert blocked EBCDIC to lower case ASCII */
877c478bd9Sstevel@tonic-gate #define UCASCII 18 /* convert blocked EBCDIC to upper case ASCII */
887c478bd9Sstevel@tonic-gate #define BLOCK 19 /* convert ASCII to blocked ASCII */
897c478bd9Sstevel@tonic-gate #define LCBLOCK 20 /* convert ASCII to lower case blocked ASCII */
907c478bd9Sstevel@tonic-gate #define UCBLOCK 21 /* convert ASCII to upper case blocked ASCII */
917c478bd9Sstevel@tonic-gate #define EBCDIC 22 /* convert ASCII to blocked EBCDIC */
927c478bd9Sstevel@tonic-gate #define LCEBCDIC 23 /* convert ASCII to lower case blocked EBCDIC */
937c478bd9Sstevel@tonic-gate #define UCEBCDIC 24 /* convert ASCII to upper case blocked EBCDIC */
947c478bd9Sstevel@tonic-gate #define IBM 25 /* convert ASCII to blocked IBM */
957c478bd9Sstevel@tonic-gate #define LCIBM 26 /* convert ASCII to lower case blocked IBM */
967c478bd9Sstevel@tonic-gate #define UCIBM 27 /* convert ASCII to upper case blocked IBM */
977c478bd9Sstevel@tonic-gate #define LCASE 01 /* flag - convert to lower case */
987c478bd9Sstevel@tonic-gate #define UCASE 02 /* flag - convert to upper case */
997c478bd9Sstevel@tonic-gate #define SWAB 04 /* flag - swap bytes before conversion */
1007c478bd9Sstevel@tonic-gate #define NERR 010 /* flag - proceed on input errors */
1017c478bd9Sstevel@tonic-gate #define SYNC 020 /* flag - pad short input blocks with nulls */
102c232df92SToomas Soome #define FULLBLOCK 040 /* flag - accumulate full blocks of input */
1037c478bd9Sstevel@tonic-gate #define BADLIMIT 5 /* give up if no progress after BADLIMIT trys */
1047c478bd9Sstevel@tonic-gate #define SVR4XLATE 0 /* use default EBCDIC translation */
1057c478bd9Sstevel@tonic-gate #define BSDXLATE 1 /* use BSD-compatible EBCDIC translation */
1067c478bd9Sstevel@tonic-gate
1077c478bd9Sstevel@tonic-gate #define USAGE\
1087c478bd9Sstevel@tonic-gate "usage: dd [if=file] [of=file] [ibs=n|nk|nb|nxm] [obs=n|nk|nb|nxm]\n"\
1097c478bd9Sstevel@tonic-gate " [bs=n|nk|nb|nxm] [cbs=n|nk|nb|nxm] [files=n] [skip=n]\n"\
11061304e4fSPaul Dagnelie " [iseek=n] [oseek=n] [seek=n] [stride=n] [istride=n]\n"\
11161304e4fSPaul Dagnelie " [ostride=n] [count=n] [conv=[ascii][,ebcdic][,ibm]\n"\
11261304e4fSPaul Dagnelie " [,asciib][,ebcdicb][,ibmb][,block|unblock][,lcase|ucase]\n"\
11361304e4fSPaul Dagnelie " [,swab][,noerror][,notrunc][,sync]]\n"\
114c232df92SToomas Soome " [iflag=[fullblock]] [oflag=[dsync][sync]]\n"
1157c478bd9Sstevel@tonic-gate
1167c478bd9Sstevel@tonic-gate /* Global references */
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate /* Local routine declarations */
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate static int match(char *);
121*c53c97f7SRobert Mustacchi static void term(int);
122*c53c97f7SRobert Mustacchi static unsigned long long number(long long);
123*c53c97f7SRobert Mustacchi static unsigned char *flsh(void);
124*c53c97f7SRobert Mustacchi static void stats(boolean_t);
1257c478bd9Sstevel@tonic-gate
1267c478bd9Sstevel@tonic-gate /* Local data definitions */
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate static unsigned ibs; /* input buffer size */
1297c478bd9Sstevel@tonic-gate static unsigned obs; /* output buffer size */
1307c478bd9Sstevel@tonic-gate static unsigned bs; /* buffer size, overrules ibs and obs */
1317c478bd9Sstevel@tonic-gate static unsigned cbs; /* conversion buffer size, used for block conversions */
1327c478bd9Sstevel@tonic-gate static unsigned ibc; /* number of bytes still in the input buffer */
1337c478bd9Sstevel@tonic-gate static unsigned obc; /* number of bytes in the output buffer */
1347c478bd9Sstevel@tonic-gate static unsigned cbc; /* number of bytes in the conversion buffer */
1357c478bd9Sstevel@tonic-gate
1367c478bd9Sstevel@tonic-gate static int ibf; /* input file descriptor */
1377c478bd9Sstevel@tonic-gate static int obf; /* output file descriptor */
1387c478bd9Sstevel@tonic-gate static int cflag; /* conversion option flags */
139c232df92SToomas Soome static int iflag; /* input flag options */
14019d32b9aSRobert Mustacchi static int oflag; /* output flag options */
1417c478bd9Sstevel@tonic-gate static int skipf; /* if skipf == 1, skip rest of input line */
1427c478bd9Sstevel@tonic-gate static unsigned long long nifr; /* count of full input records */
1437c478bd9Sstevel@tonic-gate static unsigned long long nipr; /* count of partial input records */
1447c478bd9Sstevel@tonic-gate static unsigned long long nofr; /* count of full output records */
1457c478bd9Sstevel@tonic-gate static unsigned long long nopr; /* count of partial output records */
1467c478bd9Sstevel@tonic-gate static unsigned long long ntrunc; /* count of truncated input lines */
1477c478bd9Sstevel@tonic-gate static unsigned long long nbad; /* count of bad records since last */
1487c478bd9Sstevel@tonic-gate /* good one */
1497c478bd9Sstevel@tonic-gate static int files; /* number of input files to concatenate (tape only) */
1507c478bd9Sstevel@tonic-gate static off_t skip; /* number of input records to skip */
1517c478bd9Sstevel@tonic-gate static off_t iseekn; /* number of input records to seek past */
1527c478bd9Sstevel@tonic-gate static off_t oseekn; /* number of output records to seek past */
1537c478bd9Sstevel@tonic-gate static unsigned long long count; /* number of input records to copy */
1547c478bd9Sstevel@tonic-gate /* (0 = all) */
155e3bee069SRobert Mustacchi static boolean_t ecount; /* explicit count given */
15661304e4fSPaul Dagnelie static off_t ostriden; /* number of output blocks to skip between */
15761304e4fSPaul Dagnelie /* records */
15861304e4fSPaul Dagnelie static off_t istriden; /* number of input blocks to skip between */
15961304e4fSPaul Dagnelie /* records */
16061304e4fSPaul Dagnelie
1617c478bd9Sstevel@tonic-gate static int trantype; /* BSD or SVr4 compatible EBCDIC */
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate static char *string; /* command arg pointer */
1647c478bd9Sstevel@tonic-gate static char *ifile; /* input file name pointer */
1657c478bd9Sstevel@tonic-gate static char *ofile; /* output file name pointer */
1667c478bd9Sstevel@tonic-gate static unsigned char *ibuf; /* input buffer pointer */
1677c478bd9Sstevel@tonic-gate static unsigned char *obuf; /* output buffer pointer */
1687c478bd9Sstevel@tonic-gate
16919d32b9aSRobert Mustacchi static hrtime_t startt; /* hrtime copy started */
170*c53c97f7SRobert Mustacchi static uint64_t prog_secs; /* number of seconds of progress */
17119d32b9aSRobert Mustacchi static unsigned long long obytes; /* output bytes */
17219d32b9aSRobert Mustacchi static sig_atomic_t nstats; /* do we need to output stats */
17319d32b9aSRobert Mustacchi
174*c53c97f7SRobert Mustacchi typedef enum dd_status {
175*c53c97f7SRobert Mustacchi DD_STATUS_DEFAULT = 0,
176*c53c97f7SRobert Mustacchi DD_STATUS_NONE = 1 << 0,
177*c53c97f7SRobert Mustacchi DD_STATUS_PROGRESS = 1 << 1,
178*c53c97f7SRobert Mustacchi DD_STATUS_NOXFER = 1 << 2
179*c53c97f7SRobert Mustacchi } dd_status_t;
180*c53c97f7SRobert Mustacchi
181*c53c97f7SRobert Mustacchi static dd_status_t status_arg = DD_STATUS_DEFAULT;
182*c53c97f7SRobert Mustacchi static boolean_t stderr_tty = B_FALSE;
183*c53c97f7SRobert Mustacchi static boolean_t progress_printed = B_FALSE;
184*c53c97f7SRobert Mustacchi
1857c478bd9Sstevel@tonic-gate /* This is an EBCDIC to ASCII conversion table */
1867c478bd9Sstevel@tonic-gate /* from a proposed BTL standard April 16, 1979 */
1877c478bd9Sstevel@tonic-gate
1887c478bd9Sstevel@tonic-gate static unsigned char svr4_etoa[] =
1897c478bd9Sstevel@tonic-gate {
1907c478bd9Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
1917c478bd9Sstevel@tonic-gate 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
1927c478bd9Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
1937c478bd9Sstevel@tonic-gate 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
1947c478bd9Sstevel@tonic-gate 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
1957c478bd9Sstevel@tonic-gate 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
1967c478bd9Sstevel@tonic-gate 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
1977c478bd9Sstevel@tonic-gate 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
1987c478bd9Sstevel@tonic-gate 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
1997c478bd9Sstevel@tonic-gate 0247, 0250, 0325, 0056, 0074, 0050, 0053, 0174,
2007c478bd9Sstevel@tonic-gate 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
2017c478bd9Sstevel@tonic-gate 0260, 0261, 0041, 0044, 0052, 0051, 0073, 0176,
2027c478bd9Sstevel@tonic-gate 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
2037c478bd9Sstevel@tonic-gate 0270, 0271, 0313, 0054, 0045, 0137, 0076, 0077,
2047c478bd9Sstevel@tonic-gate 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
2057c478bd9Sstevel@tonic-gate 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
2067c478bd9Sstevel@tonic-gate 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
2077c478bd9Sstevel@tonic-gate 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
2087c478bd9Sstevel@tonic-gate 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
2097c478bd9Sstevel@tonic-gate 0161, 0162, 0136, 0314, 0315, 0316, 0317, 0320,
2107c478bd9Sstevel@tonic-gate 0321, 0345, 0163, 0164, 0165, 0166, 0167, 0170,
2117c478bd9Sstevel@tonic-gate 0171, 0172, 0322, 0323, 0324, 0133, 0326, 0327,
2127c478bd9Sstevel@tonic-gate 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
2137c478bd9Sstevel@tonic-gate 0340, 0341, 0342, 0343, 0344, 0135, 0346, 0347,
2147c478bd9Sstevel@tonic-gate 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
2157c478bd9Sstevel@tonic-gate 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
2167c478bd9Sstevel@tonic-gate 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
2177c478bd9Sstevel@tonic-gate 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
2187c478bd9Sstevel@tonic-gate 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
2197c478bd9Sstevel@tonic-gate 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
2207c478bd9Sstevel@tonic-gate 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
2217c478bd9Sstevel@tonic-gate 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
2227c478bd9Sstevel@tonic-gate };
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate /* This is an ASCII to EBCDIC conversion table */
2257c478bd9Sstevel@tonic-gate /* from a proposed BTL standard April 16, 1979 */
2267c478bd9Sstevel@tonic-gate
2277c478bd9Sstevel@tonic-gate static unsigned char svr4_atoe[] =
2287c478bd9Sstevel@tonic-gate {
2297c478bd9Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
2307c478bd9Sstevel@tonic-gate 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
2317c478bd9Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
2327c478bd9Sstevel@tonic-gate 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
2337c478bd9Sstevel@tonic-gate 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
2347c478bd9Sstevel@tonic-gate 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
2357c478bd9Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
2367c478bd9Sstevel@tonic-gate 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
2377c478bd9Sstevel@tonic-gate 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
2387c478bd9Sstevel@tonic-gate 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
2397c478bd9Sstevel@tonic-gate 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
2407c478bd9Sstevel@tonic-gate 0347, 0350, 0351, 0255, 0340, 0275, 0232, 0155,
2417c478bd9Sstevel@tonic-gate 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
2427c478bd9Sstevel@tonic-gate 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
2437c478bd9Sstevel@tonic-gate 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
2447c478bd9Sstevel@tonic-gate 0247, 0250, 0251, 0300, 0117, 0320, 0137, 0007,
2457c478bd9Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
2467c478bd9Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
2477c478bd9Sstevel@tonic-gate 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
2487c478bd9Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
2497c478bd9Sstevel@tonic-gate 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
2507c478bd9Sstevel@tonic-gate 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
2517c478bd9Sstevel@tonic-gate 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
2527c478bd9Sstevel@tonic-gate 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
2537c478bd9Sstevel@tonic-gate 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
2547c478bd9Sstevel@tonic-gate 0216, 0217, 0220, 0152, 0233, 0234, 0235, 0236,
2557c478bd9Sstevel@tonic-gate 0237, 0240, 0252, 0253, 0254, 0112, 0256, 0257,
2567c478bd9Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
2577c478bd9Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0241, 0276, 0277,
2587c478bd9Sstevel@tonic-gate 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
2597c478bd9Sstevel@tonic-gate 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
2607c478bd9Sstevel@tonic-gate 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
2617c478bd9Sstevel@tonic-gate };
2627c478bd9Sstevel@tonic-gate
2637c478bd9Sstevel@tonic-gate /* Table for ASCII to IBM (alternate EBCDIC) code conversion */
2647c478bd9Sstevel@tonic-gate
2657c478bd9Sstevel@tonic-gate static unsigned char svr4_atoibm[] =
2667c478bd9Sstevel@tonic-gate {
2677c478bd9Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
2687c478bd9Sstevel@tonic-gate 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
2697c478bd9Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
2707c478bd9Sstevel@tonic-gate 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
2717c478bd9Sstevel@tonic-gate 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
2727c478bd9Sstevel@tonic-gate 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
2737c478bd9Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
2747c478bd9Sstevel@tonic-gate 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
2757c478bd9Sstevel@tonic-gate 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
2767c478bd9Sstevel@tonic-gate 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
2777c478bd9Sstevel@tonic-gate 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
2787c478bd9Sstevel@tonic-gate 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
2797c478bd9Sstevel@tonic-gate 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
2807c478bd9Sstevel@tonic-gate 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
2817c478bd9Sstevel@tonic-gate 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
2827c478bd9Sstevel@tonic-gate 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
2837c478bd9Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
2847c478bd9Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
2857c478bd9Sstevel@tonic-gate 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
2867c478bd9Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
2877c478bd9Sstevel@tonic-gate 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
2887c478bd9Sstevel@tonic-gate 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
2897c478bd9Sstevel@tonic-gate 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
2907c478bd9Sstevel@tonic-gate 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
2917c478bd9Sstevel@tonic-gate 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
2927c478bd9Sstevel@tonic-gate 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
2937c478bd9Sstevel@tonic-gate 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
2947c478bd9Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
2957c478bd9Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
2967c478bd9Sstevel@tonic-gate 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
2977c478bd9Sstevel@tonic-gate 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
2987c478bd9Sstevel@tonic-gate 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
2997c478bd9Sstevel@tonic-gate };
3007c478bd9Sstevel@tonic-gate
3017c478bd9Sstevel@tonic-gate /* Table for conversion of ASCII to lower case ASCII */
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate static unsigned char utol[] =
3047c478bd9Sstevel@tonic-gate {
3057c478bd9Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
3067c478bd9Sstevel@tonic-gate 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
3077c478bd9Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
3087c478bd9Sstevel@tonic-gate 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
3097c478bd9Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
3107c478bd9Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
3117c478bd9Sstevel@tonic-gate 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
3127c478bd9Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
3137c478bd9Sstevel@tonic-gate 0100, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
3147c478bd9Sstevel@tonic-gate 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
3157c478bd9Sstevel@tonic-gate 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
3167c478bd9Sstevel@tonic-gate 0170, 0171, 0172, 0133, 0134, 0135, 0136, 0137,
3177c478bd9Sstevel@tonic-gate 0140, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
3187c478bd9Sstevel@tonic-gate 0150, 0151, 0152, 0153, 0154, 0155, 0156, 0157,
3197c478bd9Sstevel@tonic-gate 0160, 0161, 0162, 0163, 0164, 0165, 0166, 0167,
3207c478bd9Sstevel@tonic-gate 0170, 0171, 0172, 0173, 0174, 0175, 0176, 0177,
3217c478bd9Sstevel@tonic-gate 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
3227c478bd9Sstevel@tonic-gate 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
3237c478bd9Sstevel@tonic-gate 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
3247c478bd9Sstevel@tonic-gate 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
3257c478bd9Sstevel@tonic-gate 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
3267c478bd9Sstevel@tonic-gate 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
3277c478bd9Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
3287c478bd9Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
3297c478bd9Sstevel@tonic-gate 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
3307c478bd9Sstevel@tonic-gate 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
3317c478bd9Sstevel@tonic-gate 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
3327c478bd9Sstevel@tonic-gate 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
3337c478bd9Sstevel@tonic-gate 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
3347c478bd9Sstevel@tonic-gate 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
3357c478bd9Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
3367c478bd9Sstevel@tonic-gate 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
3377c478bd9Sstevel@tonic-gate };
3387c478bd9Sstevel@tonic-gate
3397c478bd9Sstevel@tonic-gate /* Table for conversion of ASCII to upper case ASCII */
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate static unsigned char ltou[] =
3427c478bd9Sstevel@tonic-gate {
3437c478bd9Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0004, 0005, 0006, 0007,
3447c478bd9Sstevel@tonic-gate 0010, 0011, 0012, 0013, 0014, 0015, 0016, 0017,
3457c478bd9Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0024, 0025, 0026, 0027,
3467c478bd9Sstevel@tonic-gate 0030, 0031, 0032, 0033, 0034, 0035, 0036, 0037,
3477c478bd9Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0045, 0046, 0047,
3487c478bd9Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0055, 0056, 0057,
3497c478bd9Sstevel@tonic-gate 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
3507c478bd9Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0074, 0075, 0076, 0077,
3517c478bd9Sstevel@tonic-gate 0100, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
3527c478bd9Sstevel@tonic-gate 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
3537c478bd9Sstevel@tonic-gate 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
3547c478bd9Sstevel@tonic-gate 0130, 0131, 0132, 0133, 0134, 0135, 0136, 0137,
3557c478bd9Sstevel@tonic-gate 0140, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
3567c478bd9Sstevel@tonic-gate 0110, 0111, 0112, 0113, 0114, 0115, 0116, 0117,
3577c478bd9Sstevel@tonic-gate 0120, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
3587c478bd9Sstevel@tonic-gate 0130, 0131, 0132, 0173, 0174, 0175, 0176, 0177,
3597c478bd9Sstevel@tonic-gate 0200, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
3607c478bd9Sstevel@tonic-gate 0210, 0211, 0212, 0213, 0214, 0215, 0216, 0217,
3617c478bd9Sstevel@tonic-gate 0220, 0221, 0222, 0223, 0224, 0225, 0226, 0227,
3627c478bd9Sstevel@tonic-gate 0230, 0231, 0232, 0233, 0234, 0235, 0236, 0237,
3637c478bd9Sstevel@tonic-gate 0240, 0241, 0242, 0243, 0244, 0245, 0246, 0247,
3647c478bd9Sstevel@tonic-gate 0250, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
3657c478bd9Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
3667c478bd9Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
3677c478bd9Sstevel@tonic-gate 0300, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
3687c478bd9Sstevel@tonic-gate 0310, 0311, 0312, 0313, 0314, 0315, 0316, 0317,
3697c478bd9Sstevel@tonic-gate 0320, 0321, 0322, 0323, 0324, 0325, 0326, 0327,
3707c478bd9Sstevel@tonic-gate 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
3717c478bd9Sstevel@tonic-gate 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
3727c478bd9Sstevel@tonic-gate 0350, 0351, 0352, 0353, 0354, 0355, 0356, 0357,
3737c478bd9Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
3747c478bd9Sstevel@tonic-gate 0370, 0371, 0372, 0373, 0374, 0375, 0376, 0377,
3757c478bd9Sstevel@tonic-gate };
3767c478bd9Sstevel@tonic-gate
3777c478bd9Sstevel@tonic-gate /* BSD-compatible EBCDIC to ASCII translate table */
3787c478bd9Sstevel@tonic-gate
3797c478bd9Sstevel@tonic-gate static unsigned char bsd_etoa[] =
3807c478bd9Sstevel@tonic-gate {
3817c478bd9Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0234, 0011, 0206, 0177,
3827c478bd9Sstevel@tonic-gate 0227, 0215, 0216, 0013, 0014, 0015, 0016, 0017,
3837c478bd9Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0235, 0205, 0010, 0207,
3847c478bd9Sstevel@tonic-gate 0030, 0031, 0222, 0217, 0034, 0035, 0036, 0037,
3857c478bd9Sstevel@tonic-gate 0200, 0201, 0202, 0203, 0204, 0012, 0027, 0033,
3867c478bd9Sstevel@tonic-gate 0210, 0211, 0212, 0213, 0214, 0005, 0006, 0007,
3877c478bd9Sstevel@tonic-gate 0220, 0221, 0026, 0223, 0224, 0225, 0226, 0004,
3887c478bd9Sstevel@tonic-gate 0230, 0231, 0232, 0233, 0024, 0025, 0236, 0032,
3897c478bd9Sstevel@tonic-gate 0040, 0240, 0241, 0242, 0243, 0244, 0245, 0246,
3907c478bd9Sstevel@tonic-gate 0247, 0250, 0133, 0056, 0074, 0050, 0053, 0041,
3917c478bd9Sstevel@tonic-gate 0046, 0251, 0252, 0253, 0254, 0255, 0256, 0257,
3927c478bd9Sstevel@tonic-gate 0260, 0261, 0135, 0044, 0052, 0051, 0073, 0136,
3937c478bd9Sstevel@tonic-gate 0055, 0057, 0262, 0263, 0264, 0265, 0266, 0267,
3947c478bd9Sstevel@tonic-gate 0270, 0271, 0174, 0054, 0045, 0137, 0076, 0077,
3957c478bd9Sstevel@tonic-gate 0272, 0273, 0274, 0275, 0276, 0277, 0300, 0301,
3967c478bd9Sstevel@tonic-gate 0302, 0140, 0072, 0043, 0100, 0047, 0075, 0042,
3977c478bd9Sstevel@tonic-gate 0303, 0141, 0142, 0143, 0144, 0145, 0146, 0147,
3987c478bd9Sstevel@tonic-gate 0150, 0151, 0304, 0305, 0306, 0307, 0310, 0311,
3997c478bd9Sstevel@tonic-gate 0312, 0152, 0153, 0154, 0155, 0156, 0157, 0160,
4007c478bd9Sstevel@tonic-gate 0161, 0162, 0313, 0314, 0315, 0316, 0317, 0320,
4017c478bd9Sstevel@tonic-gate 0321, 0176, 0163, 0164, 0165, 0166, 0167, 0170,
4027c478bd9Sstevel@tonic-gate 0171, 0172, 0322, 0323, 0324, 0325, 0326, 0327,
4037c478bd9Sstevel@tonic-gate 0330, 0331, 0332, 0333, 0334, 0335, 0336, 0337,
4047c478bd9Sstevel@tonic-gate 0340, 0341, 0342, 0343, 0344, 0345, 0346, 0347,
4057c478bd9Sstevel@tonic-gate 0173, 0101, 0102, 0103, 0104, 0105, 0106, 0107,
4067c478bd9Sstevel@tonic-gate 0110, 0111, 0350, 0351, 0352, 0353, 0354, 0355,
4077c478bd9Sstevel@tonic-gate 0175, 0112, 0113, 0114, 0115, 0116, 0117, 0120,
4087c478bd9Sstevel@tonic-gate 0121, 0122, 0356, 0357, 0360, 0361, 0362, 0363,
4097c478bd9Sstevel@tonic-gate 0134, 0237, 0123, 0124, 0125, 0126, 0127, 0130,
4107c478bd9Sstevel@tonic-gate 0131, 0132, 0364, 0365, 0366, 0367, 0370, 0371,
4117c478bd9Sstevel@tonic-gate 0060, 0061, 0062, 0063, 0064, 0065, 0066, 0067,
4127c478bd9Sstevel@tonic-gate 0070, 0071, 0372, 0373, 0374, 0375, 0376, 0377,
4137c478bd9Sstevel@tonic-gate };
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate /* BSD-compatible ASCII to EBCDIC translate table */
4167c478bd9Sstevel@tonic-gate
4177c478bd9Sstevel@tonic-gate static unsigned char bsd_atoe[] =
4187c478bd9Sstevel@tonic-gate {
4197c478bd9Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
4207c478bd9Sstevel@tonic-gate 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
4217c478bd9Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
4227c478bd9Sstevel@tonic-gate 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
4237c478bd9Sstevel@tonic-gate 0100, 0117, 0177, 0173, 0133, 0154, 0120, 0175,
4247c478bd9Sstevel@tonic-gate 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
4257c478bd9Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
4267c478bd9Sstevel@tonic-gate 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
4277c478bd9Sstevel@tonic-gate 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
4287c478bd9Sstevel@tonic-gate 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
4297c478bd9Sstevel@tonic-gate 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
4307c478bd9Sstevel@tonic-gate 0347, 0350, 0351, 0112, 0340, 0132, 0137, 0155,
4317c478bd9Sstevel@tonic-gate 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
4327c478bd9Sstevel@tonic-gate 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
4337c478bd9Sstevel@tonic-gate 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
4347c478bd9Sstevel@tonic-gate 0247, 0250, 0251, 0300, 0152, 0320, 0241, 0007,
4357c478bd9Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
4367c478bd9Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
4377c478bd9Sstevel@tonic-gate 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
4387c478bd9Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
4397c478bd9Sstevel@tonic-gate 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
4407c478bd9Sstevel@tonic-gate 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
4417c478bd9Sstevel@tonic-gate 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
4427c478bd9Sstevel@tonic-gate 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
4437c478bd9Sstevel@tonic-gate 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
4447c478bd9Sstevel@tonic-gate 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
4457c478bd9Sstevel@tonic-gate 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
4467c478bd9Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
4477c478bd9Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
4487c478bd9Sstevel@tonic-gate 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
4497c478bd9Sstevel@tonic-gate 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
4507c478bd9Sstevel@tonic-gate 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
4517c478bd9Sstevel@tonic-gate };
4527c478bd9Sstevel@tonic-gate
4537c478bd9Sstevel@tonic-gate /* BSD-compatible ASCII to IBM translate table */
4547c478bd9Sstevel@tonic-gate
4557c478bd9Sstevel@tonic-gate static unsigned char bsd_atoibm[] =
4567c478bd9Sstevel@tonic-gate {
4577c478bd9Sstevel@tonic-gate 0000, 0001, 0002, 0003, 0067, 0055, 0056, 0057,
4587c478bd9Sstevel@tonic-gate 0026, 0005, 0045, 0013, 0014, 0015, 0016, 0017,
4597c478bd9Sstevel@tonic-gate 0020, 0021, 0022, 0023, 0074, 0075, 0062, 0046,
4607c478bd9Sstevel@tonic-gate 0030, 0031, 0077, 0047, 0034, 0035, 0036, 0037,
4617c478bd9Sstevel@tonic-gate 0100, 0132, 0177, 0173, 0133, 0154, 0120, 0175,
4627c478bd9Sstevel@tonic-gate 0115, 0135, 0134, 0116, 0153, 0140, 0113, 0141,
4637c478bd9Sstevel@tonic-gate 0360, 0361, 0362, 0363, 0364, 0365, 0366, 0367,
4647c478bd9Sstevel@tonic-gate 0370, 0371, 0172, 0136, 0114, 0176, 0156, 0157,
4657c478bd9Sstevel@tonic-gate 0174, 0301, 0302, 0303, 0304, 0305, 0306, 0307,
4667c478bd9Sstevel@tonic-gate 0310, 0311, 0321, 0322, 0323, 0324, 0325, 0326,
4677c478bd9Sstevel@tonic-gate 0327, 0330, 0331, 0342, 0343, 0344, 0345, 0346,
4687c478bd9Sstevel@tonic-gate 0347, 0350, 0351, 0255, 0340, 0275, 0137, 0155,
4697c478bd9Sstevel@tonic-gate 0171, 0201, 0202, 0203, 0204, 0205, 0206, 0207,
4707c478bd9Sstevel@tonic-gate 0210, 0211, 0221, 0222, 0223, 0224, 0225, 0226,
4717c478bd9Sstevel@tonic-gate 0227, 0230, 0231, 0242, 0243, 0244, 0245, 0246,
4727c478bd9Sstevel@tonic-gate 0247, 0250, 0251, 0300, 0117, 0320, 0241, 0007,
4737c478bd9Sstevel@tonic-gate 0040, 0041, 0042, 0043, 0044, 0025, 0006, 0027,
4747c478bd9Sstevel@tonic-gate 0050, 0051, 0052, 0053, 0054, 0011, 0012, 0033,
4757c478bd9Sstevel@tonic-gate 0060, 0061, 0032, 0063, 0064, 0065, 0066, 0010,
4767c478bd9Sstevel@tonic-gate 0070, 0071, 0072, 0073, 0004, 0024, 0076, 0341,
4777c478bd9Sstevel@tonic-gate 0101, 0102, 0103, 0104, 0105, 0106, 0107, 0110,
4787c478bd9Sstevel@tonic-gate 0111, 0121, 0122, 0123, 0124, 0125, 0126, 0127,
4797c478bd9Sstevel@tonic-gate 0130, 0131, 0142, 0143, 0144, 0145, 0146, 0147,
4807c478bd9Sstevel@tonic-gate 0150, 0151, 0160, 0161, 0162, 0163, 0164, 0165,
4817c478bd9Sstevel@tonic-gate 0166, 0167, 0170, 0200, 0212, 0213, 0214, 0215,
4827c478bd9Sstevel@tonic-gate 0216, 0217, 0220, 0232, 0233, 0234, 0235, 0236,
4837c478bd9Sstevel@tonic-gate 0237, 0240, 0252, 0253, 0254, 0255, 0256, 0257,
4847c478bd9Sstevel@tonic-gate 0260, 0261, 0262, 0263, 0264, 0265, 0266, 0267,
4857c478bd9Sstevel@tonic-gate 0270, 0271, 0272, 0273, 0274, 0275, 0276, 0277,
4867c478bd9Sstevel@tonic-gate 0312, 0313, 0314, 0315, 0316, 0317, 0332, 0333,
4877c478bd9Sstevel@tonic-gate 0334, 0335, 0336, 0337, 0352, 0353, 0354, 0355,
4887c478bd9Sstevel@tonic-gate 0356, 0357, 0372, 0373, 0374, 0375, 0376, 0377,
4897c478bd9Sstevel@tonic-gate };
4907c478bd9Sstevel@tonic-gate
4917c478bd9Sstevel@tonic-gate /* set up to use SVr4 ascii-ebcdic translation by default */
4927c478bd9Sstevel@tonic-gate
4937c478bd9Sstevel@tonic-gate static unsigned char *atoe = svr4_atoe;
4947c478bd9Sstevel@tonic-gate static unsigned char *etoa = svr4_etoa;
4957c478bd9Sstevel@tonic-gate static unsigned char *atoibm = svr4_atoibm;
4967c478bd9Sstevel@tonic-gate
49719d32b9aSRobert Mustacchi /*ARGSUSED*/
49819d32b9aSRobert Mustacchi static void
siginfo_handler(int sig,siginfo_t * sip,void * ucp)49919d32b9aSRobert Mustacchi siginfo_handler(int sig, siginfo_t *sip, void *ucp)
50019d32b9aSRobert Mustacchi {
50119d32b9aSRobert Mustacchi nstats = 1;
50219d32b9aSRobert Mustacchi }
5037c478bd9Sstevel@tonic-gate
504c232df92SToomas Soome static ssize_t
iread(int fd,char * buf,size_t nbyte)505c232df92SToomas Soome iread(int fd, char *buf, size_t nbyte)
506c232df92SToomas Soome {
507c232df92SToomas Soome ssize_t count;
508c232df92SToomas Soome
509c232df92SToomas Soome count = 0;
510c232df92SToomas Soome while (nbyte != 0) {
511c232df92SToomas Soome ssize_t nr = read(fd, buf, nbyte);
512c232df92SToomas Soome
513c232df92SToomas Soome if (nr < 0)
514c232df92SToomas Soome return (nr);
515c232df92SToomas Soome
516c232df92SToomas Soome if (nr == 0)
517c232df92SToomas Soome break;
518c232df92SToomas Soome buf += nr;
519c232df92SToomas Soome count += nr;
520c232df92SToomas Soome nbyte -= nr;
521c232df92SToomas Soome
522c232df92SToomas Soome if ((iflag & FULLBLOCK) == 0)
523c232df92SToomas Soome break;
524c232df92SToomas Soome }
525c232df92SToomas Soome return (count);
526c232df92SToomas Soome }
527c232df92SToomas Soome
528a77d64afScf46844 int
main(int argc,char ** argv)529a77d64afScf46844 main(int argc, char **argv)
5307c478bd9Sstevel@tonic-gate {
5317c478bd9Sstevel@tonic-gate unsigned char *ip, *op; /* input and output buffer pointers */
5327c478bd9Sstevel@tonic-gate int c; /* character counter */
5337c478bd9Sstevel@tonic-gate int ic; /* input character */
5347c478bd9Sstevel@tonic-gate int conv; /* conversion option code */
5357c478bd9Sstevel@tonic-gate int trunc; /* whether output file is truncated */
5367c478bd9Sstevel@tonic-gate struct stat file_stat;
53719d32b9aSRobert Mustacchi struct sigaction sact;
5387c478bd9Sstevel@tonic-gate
5397c478bd9Sstevel@tonic-gate /* Set option defaults */
5407c478bd9Sstevel@tonic-gate
5417c478bd9Sstevel@tonic-gate ibs = BSIZE;
5427c478bd9Sstevel@tonic-gate obs = BSIZE;
5437c478bd9Sstevel@tonic-gate files = 1;
5447c478bd9Sstevel@tonic-gate conv = COPY;
5457c478bd9Sstevel@tonic-gate trunc = 1; /* default: truncate output file */
5467c478bd9Sstevel@tonic-gate trantype = SVR4XLATE; /* use SVR4 EBCDIC by default */
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate /* Parse command options */
5497c478bd9Sstevel@tonic-gate
5507c478bd9Sstevel@tonic-gate (void) setlocale(LC_ALL, "");
5517c478bd9Sstevel@tonic-gate #if !defined(TEXT_DOMAIN) /* Should be defined by cc -D */
5527c478bd9Sstevel@tonic-gate #define TEXT_DOMAIN "SYS_TEST" /* Use this only if it weren't */
5537c478bd9Sstevel@tonic-gate #endif
5547c478bd9Sstevel@tonic-gate (void) textdomain(TEXT_DOMAIN);
5557c478bd9Sstevel@tonic-gate
5567c478bd9Sstevel@tonic-gate while ((c = getopt(argc, argv, "")) != EOF)
5577c478bd9Sstevel@tonic-gate switch (c) {
5587c478bd9Sstevel@tonic-gate case '?':
5597c478bd9Sstevel@tonic-gate (void) fprintf(stderr, USAGE);
5607c478bd9Sstevel@tonic-gate exit(2);
5617c478bd9Sstevel@tonic-gate }
5627c478bd9Sstevel@tonic-gate
5637c478bd9Sstevel@tonic-gate /* not getopt()'ed because dd has no options but only operand(s) */
5647c478bd9Sstevel@tonic-gate
565b928ac84SToomas Soome for (c = optind; c < argc; c++) {
5667c478bd9Sstevel@tonic-gate string = argv[c];
567b928ac84SToomas Soome if (match("ibs=")) {
5687c478bd9Sstevel@tonic-gate ibs = (unsigned)number(BIG);
5697c478bd9Sstevel@tonic-gate continue;
5707c478bd9Sstevel@tonic-gate }
571b928ac84SToomas Soome if (match("obs=")) {
5727c478bd9Sstevel@tonic-gate obs = (unsigned)number(BIG);
5737c478bd9Sstevel@tonic-gate continue;
5747c478bd9Sstevel@tonic-gate }
575b928ac84SToomas Soome if (match("cbs=")) {
5767c478bd9Sstevel@tonic-gate cbs = (unsigned)number(BIG);
5777c478bd9Sstevel@tonic-gate continue;
5787c478bd9Sstevel@tonic-gate }
579b928ac84SToomas Soome if (match("bs=")) {
5807c478bd9Sstevel@tonic-gate bs = (unsigned)number(BIG);
5817c478bd9Sstevel@tonic-gate continue;
5827c478bd9Sstevel@tonic-gate }
583b928ac84SToomas Soome if (match("if=")) {
5847c478bd9Sstevel@tonic-gate ifile = string;
5857c478bd9Sstevel@tonic-gate continue;
5867c478bd9Sstevel@tonic-gate }
587b928ac84SToomas Soome if (match("of=")) {
5887c478bd9Sstevel@tonic-gate ofile = string;
5897c478bd9Sstevel@tonic-gate continue;
5907c478bd9Sstevel@tonic-gate }
591b928ac84SToomas Soome if (match("skip=")) {
5927c478bd9Sstevel@tonic-gate skip = number(BIG);
5937c478bd9Sstevel@tonic-gate continue;
5947c478bd9Sstevel@tonic-gate }
595b928ac84SToomas Soome if (match("iseek=")) {
5967c478bd9Sstevel@tonic-gate iseekn = number(BIG);
5977c478bd9Sstevel@tonic-gate continue;
5987c478bd9Sstevel@tonic-gate }
599b928ac84SToomas Soome if (match("oseek=")) {
6007c478bd9Sstevel@tonic-gate oseekn = number(BIG);
6017c478bd9Sstevel@tonic-gate continue;
6027c478bd9Sstevel@tonic-gate }
603b928ac84SToomas Soome if (match("seek=")) { /* retained for compatibility */
6047c478bd9Sstevel@tonic-gate oseekn = number(BIG);
6057c478bd9Sstevel@tonic-gate continue;
6067c478bd9Sstevel@tonic-gate }
607b928ac84SToomas Soome if (match("ostride=")) {
60861304e4fSPaul Dagnelie ostriden = ((off_t)number(BIG)) - 1;
60961304e4fSPaul Dagnelie continue;
61061304e4fSPaul Dagnelie }
611b928ac84SToomas Soome if (match("istride=")) {
61261304e4fSPaul Dagnelie istriden = ((off_t)number(BIG)) - 1;
61361304e4fSPaul Dagnelie continue;
61461304e4fSPaul Dagnelie }
615b928ac84SToomas Soome if (match("stride=")) {
61661304e4fSPaul Dagnelie istriden = ostriden = ((off_t)number(BIG)) - 1;
61761304e4fSPaul Dagnelie continue;
61861304e4fSPaul Dagnelie }
619b928ac84SToomas Soome if (match("count=")) {
6207c478bd9Sstevel@tonic-gate count = number(BIG);
621e3bee069SRobert Mustacchi ecount = B_TRUE;
6227c478bd9Sstevel@tonic-gate continue;
6237c478bd9Sstevel@tonic-gate }
624b928ac84SToomas Soome if (match("files=")) {
6257c478bd9Sstevel@tonic-gate files = (int)number(BIG);
6267c478bd9Sstevel@tonic-gate continue;
6277c478bd9Sstevel@tonic-gate }
628b928ac84SToomas Soome if (match("conv=")) {
629b928ac84SToomas Soome for (;;) {
630b928ac84SToomas Soome if (match(",")) {
6317c478bd9Sstevel@tonic-gate continue;
6327c478bd9Sstevel@tonic-gate }
633b928ac84SToomas Soome if (*string == '\0') {
6347c478bd9Sstevel@tonic-gate break;
6357c478bd9Sstevel@tonic-gate }
636b928ac84SToomas Soome if (match("block")) {
6377c478bd9Sstevel@tonic-gate conv = BLOCK;
6387c478bd9Sstevel@tonic-gate continue;
6397c478bd9Sstevel@tonic-gate }
640b928ac84SToomas Soome if (match("unblock")) {
6417c478bd9Sstevel@tonic-gate conv = UNBLOCK;
6427c478bd9Sstevel@tonic-gate continue;
6437c478bd9Sstevel@tonic-gate }
6447c478bd9Sstevel@tonic-gate
6457c478bd9Sstevel@tonic-gate /* ebcdicb, ibmb, and asciib must precede */
6467c478bd9Sstevel@tonic-gate /* ebcdic, ibm, and ascii in this test */
6477c478bd9Sstevel@tonic-gate
648b928ac84SToomas Soome if (match("ebcdicb")) {
6497c478bd9Sstevel@tonic-gate conv = EBCDIC;
6507c478bd9Sstevel@tonic-gate trantype = BSDXLATE;
6517c478bd9Sstevel@tonic-gate continue;
6527c478bd9Sstevel@tonic-gate }
653b928ac84SToomas Soome if (match("ibmb")) {
6547c478bd9Sstevel@tonic-gate conv = IBM;
6557c478bd9Sstevel@tonic-gate trantype = BSDXLATE;
6567c478bd9Sstevel@tonic-gate continue;
6577c478bd9Sstevel@tonic-gate }
658b928ac84SToomas Soome if (match("asciib")) {
6597c478bd9Sstevel@tonic-gate conv = ASCII;
6607c478bd9Sstevel@tonic-gate trantype = BSDXLATE;
6617c478bd9Sstevel@tonic-gate continue;
6627c478bd9Sstevel@tonic-gate }
663b928ac84SToomas Soome if (match("ebcdic")) {
6647c478bd9Sstevel@tonic-gate conv = EBCDIC;
6657c478bd9Sstevel@tonic-gate trantype = SVR4XLATE;
6667c478bd9Sstevel@tonic-gate continue;
6677c478bd9Sstevel@tonic-gate }
668b928ac84SToomas Soome if (match("ibm")) {
6697c478bd9Sstevel@tonic-gate conv = IBM;
6707c478bd9Sstevel@tonic-gate trantype = SVR4XLATE;
6717c478bd9Sstevel@tonic-gate continue;
6727c478bd9Sstevel@tonic-gate }
673b928ac84SToomas Soome if (match("ascii")) {
6747c478bd9Sstevel@tonic-gate conv = ASCII;
6757c478bd9Sstevel@tonic-gate trantype = SVR4XLATE;
6767c478bd9Sstevel@tonic-gate continue;
6777c478bd9Sstevel@tonic-gate }
678b928ac84SToomas Soome if (match("lcase")) {
6797c478bd9Sstevel@tonic-gate cflag |= LCASE;
6807c478bd9Sstevel@tonic-gate continue;
6817c478bd9Sstevel@tonic-gate }
682b928ac84SToomas Soome if (match("ucase")) {
6837c478bd9Sstevel@tonic-gate cflag |= UCASE;
6847c478bd9Sstevel@tonic-gate continue;
6857c478bd9Sstevel@tonic-gate }
686b928ac84SToomas Soome if (match("swab")) {
6877c478bd9Sstevel@tonic-gate cflag |= SWAB;
6887c478bd9Sstevel@tonic-gate continue;
6897c478bd9Sstevel@tonic-gate }
690b928ac84SToomas Soome if (match("noerror")) {
6917c478bd9Sstevel@tonic-gate cflag |= NERR;
6927c478bd9Sstevel@tonic-gate continue;
6937c478bd9Sstevel@tonic-gate }
694b928ac84SToomas Soome if (match("notrunc")) {
6957c478bd9Sstevel@tonic-gate trunc = 0;
6967c478bd9Sstevel@tonic-gate continue;
6977c478bd9Sstevel@tonic-gate }
698b928ac84SToomas Soome if (match("sync")) {
6997c478bd9Sstevel@tonic-gate cflag |= SYNC;
7007c478bd9Sstevel@tonic-gate continue;
7017c478bd9Sstevel@tonic-gate }
7027c478bd9Sstevel@tonic-gate goto badarg;
7037c478bd9Sstevel@tonic-gate }
7047c478bd9Sstevel@tonic-gate continue;
7057c478bd9Sstevel@tonic-gate }
706c232df92SToomas Soome if (match("iflag=")) {
707c232df92SToomas Soome for (;;) {
708c232df92SToomas Soome if (match(",")) {
709c232df92SToomas Soome continue;
710c232df92SToomas Soome }
711c232df92SToomas Soome if (*string == '\0') {
712c232df92SToomas Soome break;
713c232df92SToomas Soome }
714c232df92SToomas Soome if (match("fullblock")) {
715c232df92SToomas Soome iflag |= FULLBLOCK;
716c232df92SToomas Soome continue;
717c232df92SToomas Soome }
718c232df92SToomas Soome goto badarg;
719c232df92SToomas Soome }
720c232df92SToomas Soome continue;
721c232df92SToomas Soome }
722b928ac84SToomas Soome if (match("oflag=")) {
723b928ac84SToomas Soome for (;;) {
724b928ac84SToomas Soome if (match(",")) {
72519d32b9aSRobert Mustacchi continue;
72619d32b9aSRobert Mustacchi }
727b928ac84SToomas Soome if (*string == '\0') {
72819d32b9aSRobert Mustacchi break;
72919d32b9aSRobert Mustacchi }
730b928ac84SToomas Soome if (match("dsync")) {
73119d32b9aSRobert Mustacchi oflag |= O_DSYNC;
73219d32b9aSRobert Mustacchi continue;
73319d32b9aSRobert Mustacchi }
734b928ac84SToomas Soome if (match("sync")) {
73519d32b9aSRobert Mustacchi oflag |= O_SYNC;
73619d32b9aSRobert Mustacchi continue;
73719d32b9aSRobert Mustacchi }
73819d32b9aSRobert Mustacchi goto badarg;
73919d32b9aSRobert Mustacchi }
74019d32b9aSRobert Mustacchi continue;
74119d32b9aSRobert Mustacchi }
742*c53c97f7SRobert Mustacchi if (match("status=")) {
743*c53c97f7SRobert Mustacchi if (match("none")) {
744*c53c97f7SRobert Mustacchi status_arg = DD_STATUS_NONE;
745*c53c97f7SRobert Mustacchi } else if (match("noxfer")) {
746*c53c97f7SRobert Mustacchi status_arg = DD_STATUS_NOXFER;
747*c53c97f7SRobert Mustacchi } else if (match("progress")) {
748*c53c97f7SRobert Mustacchi status_arg = DD_STATUS_PROGRESS;
749*c53c97f7SRobert Mustacchi } else {
750*c53c97f7SRobert Mustacchi goto badarg;
751*c53c97f7SRobert Mustacchi }
752*c53c97f7SRobert Mustacchi continue;
753*c53c97f7SRobert Mustacchi }
7547c478bd9Sstevel@tonic-gate badarg:
7557c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s \"%s\"\n",
7567c478bd9Sstevel@tonic-gate gettext("bad argument:"), string);
7577c478bd9Sstevel@tonic-gate exit(2);
7587c478bd9Sstevel@tonic-gate }
7597c478bd9Sstevel@tonic-gate
7607c478bd9Sstevel@tonic-gate /* Perform consistency checks on options, decode strange conventions */
7617c478bd9Sstevel@tonic-gate
762b928ac84SToomas Soome if (bs) {
7637c478bd9Sstevel@tonic-gate ibs = obs = bs;
7647c478bd9Sstevel@tonic-gate }
765b928ac84SToomas Soome if ((ibs == 0) || (obs == 0)) {
7667c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s\n",
7677c478bd9Sstevel@tonic-gate gettext("buffer sizes cannot be zero"));
7687c478bd9Sstevel@tonic-gate exit(2);
7697c478bd9Sstevel@tonic-gate }
77061304e4fSPaul Dagnelie if (ostriden == (off_t)-1) {
77161304e4fSPaul Dagnelie (void) fprintf(stderr, "dd: %s\n",
77261304e4fSPaul Dagnelie gettext("stride must be greater than zero"));
77361304e4fSPaul Dagnelie exit(2);
77461304e4fSPaul Dagnelie }
77561304e4fSPaul Dagnelie if (istriden == (off_t)-1) {
77661304e4fSPaul Dagnelie (void) fprintf(stderr, "dd: %s\n",
77761304e4fSPaul Dagnelie gettext("stride must be greater than zero"));
77861304e4fSPaul Dagnelie exit(2);
77961304e4fSPaul Dagnelie }
780b928ac84SToomas Soome if (conv == COPY) {
781b928ac84SToomas Soome if ((bs == 0) || (cflag & (LCASE | UCASE))) {
7827c478bd9Sstevel@tonic-gate conv = REBLOCK;
7837c478bd9Sstevel@tonic-gate }
7847c478bd9Sstevel@tonic-gate }
785b928ac84SToomas Soome if (cbs == 0) {
786b928ac84SToomas Soome switch (conv) {
7877c478bd9Sstevel@tonic-gate case BLOCK:
7887c478bd9Sstevel@tonic-gate case UNBLOCK:
7897c478bd9Sstevel@tonic-gate conv = REBLOCK;
7907c478bd9Sstevel@tonic-gate break;
7917c478bd9Sstevel@tonic-gate
7927c478bd9Sstevel@tonic-gate case ASCII:
7937c478bd9Sstevel@tonic-gate conv = NBASCII;
7947c478bd9Sstevel@tonic-gate break;
7957c478bd9Sstevel@tonic-gate
7967c478bd9Sstevel@tonic-gate case EBCDIC:
7977c478bd9Sstevel@tonic-gate conv = NBEBCDIC;
7987c478bd9Sstevel@tonic-gate break;
7997c478bd9Sstevel@tonic-gate
8007c478bd9Sstevel@tonic-gate case IBM:
8017c478bd9Sstevel@tonic-gate conv = NBIBM;
8027c478bd9Sstevel@tonic-gate break;
8037c478bd9Sstevel@tonic-gate }
8047c478bd9Sstevel@tonic-gate }
8057c478bd9Sstevel@tonic-gate
8067c478bd9Sstevel@tonic-gate /* Expand options into lower and upper case versions if necessary */
8077c478bd9Sstevel@tonic-gate
808b928ac84SToomas Soome switch (conv) {
8097c478bd9Sstevel@tonic-gate case REBLOCK:
8107c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8117c478bd9Sstevel@tonic-gate conv = LCREBLOCK;
8127c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8137c478bd9Sstevel@tonic-gate conv = UCREBLOCK;
8147c478bd9Sstevel@tonic-gate break;
8157c478bd9Sstevel@tonic-gate
8167c478bd9Sstevel@tonic-gate case UNBLOCK:
8177c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8187c478bd9Sstevel@tonic-gate conv = LCUNBLOCK;
8197c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8207c478bd9Sstevel@tonic-gate conv = UCUNBLOCK;
8217c478bd9Sstevel@tonic-gate break;
8227c478bd9Sstevel@tonic-gate
8237c478bd9Sstevel@tonic-gate case BLOCK:
8247c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8257c478bd9Sstevel@tonic-gate conv = LCBLOCK;
8267c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8277c478bd9Sstevel@tonic-gate conv = UCBLOCK;
8287c478bd9Sstevel@tonic-gate break;
8297c478bd9Sstevel@tonic-gate
8307c478bd9Sstevel@tonic-gate case ASCII:
8317c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8327c478bd9Sstevel@tonic-gate conv = LCASCII;
8337c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8347c478bd9Sstevel@tonic-gate conv = UCASCII;
8357c478bd9Sstevel@tonic-gate break;
8367c478bd9Sstevel@tonic-gate
8377c478bd9Sstevel@tonic-gate case NBASCII:
8387c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8397c478bd9Sstevel@tonic-gate conv = LCNBASCII;
8407c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8417c478bd9Sstevel@tonic-gate conv = UCNBASCII;
8427c478bd9Sstevel@tonic-gate break;
8437c478bd9Sstevel@tonic-gate
8447c478bd9Sstevel@tonic-gate case EBCDIC:
8457c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8467c478bd9Sstevel@tonic-gate conv = LCEBCDIC;
8477c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8487c478bd9Sstevel@tonic-gate conv = UCEBCDIC;
8497c478bd9Sstevel@tonic-gate break;
8507c478bd9Sstevel@tonic-gate
8517c478bd9Sstevel@tonic-gate case NBEBCDIC:
8527c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8537c478bd9Sstevel@tonic-gate conv = LCNBEBCDIC;
8547c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8557c478bd9Sstevel@tonic-gate conv = UCNBEBCDIC;
8567c478bd9Sstevel@tonic-gate break;
8577c478bd9Sstevel@tonic-gate
8587c478bd9Sstevel@tonic-gate case IBM:
8597c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8607c478bd9Sstevel@tonic-gate conv = LCIBM;
8617c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8627c478bd9Sstevel@tonic-gate conv = UCIBM;
8637c478bd9Sstevel@tonic-gate break;
8647c478bd9Sstevel@tonic-gate
8657c478bd9Sstevel@tonic-gate case NBIBM:
8667c478bd9Sstevel@tonic-gate if (cflag & LCASE)
8677c478bd9Sstevel@tonic-gate conv = LCNBIBM;
8687c478bd9Sstevel@tonic-gate else if (cflag & UCASE)
8697c478bd9Sstevel@tonic-gate conv = UCNBIBM;
8707c478bd9Sstevel@tonic-gate break;
8717c478bd9Sstevel@tonic-gate }
8727c478bd9Sstevel@tonic-gate
8737c478bd9Sstevel@tonic-gate /* If BSD-compatible translation is selected, change the tables */
8747c478bd9Sstevel@tonic-gate
8757c478bd9Sstevel@tonic-gate if (trantype == BSDXLATE) {
8767c478bd9Sstevel@tonic-gate atoe = bsd_atoe;
8777c478bd9Sstevel@tonic-gate atoibm = bsd_atoibm;
8787c478bd9Sstevel@tonic-gate etoa = bsd_etoa;
8797c478bd9Sstevel@tonic-gate }
8807c478bd9Sstevel@tonic-gate /* Open the input file, or duplicate standard input */
8817c478bd9Sstevel@tonic-gate
8827c478bd9Sstevel@tonic-gate ibf = -1;
883b928ac84SToomas Soome if (ifile) {
8847c478bd9Sstevel@tonic-gate ibf = open(ifile, 0);
885b928ac84SToomas Soome } else {
8867c478bd9Sstevel@tonic-gate ifile = "";
887b928ac84SToomas Soome ibf = dup(STDIN_FILENO);
8887c478bd9Sstevel@tonic-gate }
88919d32b9aSRobert Mustacchi
890b928ac84SToomas Soome if (ibf == -1) {
8917c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s: ", ifile);
8927c478bd9Sstevel@tonic-gate perror("open");
8937c478bd9Sstevel@tonic-gate exit(2);
8947c478bd9Sstevel@tonic-gate }
8957c478bd9Sstevel@tonic-gate
8967c478bd9Sstevel@tonic-gate /* Open the output file, or duplicate standard output */
8977c478bd9Sstevel@tonic-gate
8987c478bd9Sstevel@tonic-gate obf = -1;
899b928ac84SToomas Soome if (ofile) {
900b928ac84SToomas Soome if (trunc == 0) { /* do not truncate output file */
90119d32b9aSRobert Mustacchi obf = open(ofile, (O_WRONLY | O_CREAT | oflag),
902b928ac84SToomas Soome (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
903b928ac84SToomas Soome S_IROTH | S_IWOTH));
904b928ac84SToomas Soome } else if (oseekn && (trunc == 1)) {
90519d32b9aSRobert Mustacchi obf = open(ofile, O_WRONLY | O_CREAT | oflag,
906b928ac84SToomas Soome (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
907b928ac84SToomas Soome S_IROTH | S_IWOTH));
908b928ac84SToomas Soome if (obf == -1) {
9097c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s: ", ofile);
9107c478bd9Sstevel@tonic-gate perror("open");
9117c478bd9Sstevel@tonic-gate exit(2);
9127c478bd9Sstevel@tonic-gate }
9137c478bd9Sstevel@tonic-gate (void) fstat(obf, &file_stat);
9147c478bd9Sstevel@tonic-gate if (((file_stat.st_mode & S_IFMT) == S_IFREG) &&
9157c478bd9Sstevel@tonic-gate (ftruncate(obf, (((off_t)oseekn) * ((off_t)obs)))
916b928ac84SToomas Soome == -1)) {
9177c478bd9Sstevel@tonic-gate perror("ftruncate");
9187c478bd9Sstevel@tonic-gate exit(2);
9197c478bd9Sstevel@tonic-gate }
920b928ac84SToomas Soome } else {
92119d32b9aSRobert Mustacchi obf = open(ofile, O_WRONLY | O_CREAT | O_TRUNC | oflag,
922b928ac84SToomas Soome (S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP |
923b928ac84SToomas Soome S_IROTH | S_IWOTH));
9247c478bd9Sstevel@tonic-gate }
925b928ac84SToomas Soome } else {
9267c478bd9Sstevel@tonic-gate ofile = "";
927b928ac84SToomas Soome obf = dup(STDOUT_FILENO);
9287c478bd9Sstevel@tonic-gate }
92919d32b9aSRobert Mustacchi
930b928ac84SToomas Soome if (obf == -1) {
9317c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s: ", ofile);
9327c478bd9Sstevel@tonic-gate perror("open");
9337c478bd9Sstevel@tonic-gate exit(2);
9347c478bd9Sstevel@tonic-gate }
9357c478bd9Sstevel@tonic-gate
9367c478bd9Sstevel@tonic-gate /* Expand memory to get an input buffer */
9377c478bd9Sstevel@tonic-gate
9387c478bd9Sstevel@tonic-gate ibuf = (unsigned char *)valloc(ibs + 10);
9397c478bd9Sstevel@tonic-gate
9407c478bd9Sstevel@tonic-gate /* If no conversions, the input buffer is the output buffer */
9417c478bd9Sstevel@tonic-gate
942b928ac84SToomas Soome if (conv == COPY) {
9437c478bd9Sstevel@tonic-gate obuf = ibuf;
944b928ac84SToomas Soome } else {
9457c478bd9Sstevel@tonic-gate
946b928ac84SToomas Soome /*
947b928ac84SToomas Soome * Expand memory to get an output buffer. Leave enough room
948b928ac84SToomas Soome * at the end to convert a logical record when doing block
949b928ac84SToomas Soome * conversions.
950b928ac84SToomas Soome */
9517c478bd9Sstevel@tonic-gate
9527c478bd9Sstevel@tonic-gate obuf = (unsigned char *)valloc(obs + cbs + 10);
9537c478bd9Sstevel@tonic-gate }
954b928ac84SToomas Soome if ((ibuf == NULL) || (obuf == NULL)) {
9557c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
9567c478bd9Sstevel@tonic-gate "dd: %s\n", gettext("not enough memory"));
9577c478bd9Sstevel@tonic-gate exit(2);
9587c478bd9Sstevel@tonic-gate }
9597c478bd9Sstevel@tonic-gate
96019d32b9aSRobert Mustacchi /*
96119d32b9aSRobert Mustacchi * Enable a statistics message when we terminate on SIGINT
96219d32b9aSRobert Mustacchi * Also enable it to be queried via SIGINFO and SIGUSR1
96319d32b9aSRobert Mustacchi */
9647c478bd9Sstevel@tonic-gate
965b928ac84SToomas Soome if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
9667c478bd9Sstevel@tonic-gate (void) signal(SIGINT, term);
9677c478bd9Sstevel@tonic-gate }
96819d32b9aSRobert Mustacchi
96919d32b9aSRobert Mustacchi bzero(&sact, sizeof (struct sigaction));
97019d32b9aSRobert Mustacchi sact.sa_flags = SA_SIGINFO;
97119d32b9aSRobert Mustacchi sact.sa_sigaction = siginfo_handler;
97219d32b9aSRobert Mustacchi (void) sigemptyset(&sact.sa_mask);
97319d32b9aSRobert Mustacchi if (sigaction(SIGINFO, &sact, NULL) != 0) {
97419d32b9aSRobert Mustacchi (void) fprintf(stderr, "dd: %s: %s\n",
97519d32b9aSRobert Mustacchi gettext("failed to enable siginfo handler"),
97619d32b9aSRobert Mustacchi gettext(strerror(errno)));
97719d32b9aSRobert Mustacchi exit(2);
97819d32b9aSRobert Mustacchi }
97919d32b9aSRobert Mustacchi if (sigaction(SIGUSR1, &sact, NULL) != 0) {
98019d32b9aSRobert Mustacchi (void) fprintf(stderr, "dd: %s: %s\n",
98119d32b9aSRobert Mustacchi gettext("failed to enable sigusr1 handler"),
98219d32b9aSRobert Mustacchi gettext(strerror(errno)));
98319d32b9aSRobert Mustacchi exit(2);
98419d32b9aSRobert Mustacchi }
98519d32b9aSRobert Mustacchi
986*c53c97f7SRobert Mustacchi /*
987*c53c97f7SRobert Mustacchi * Determine if stderr is a tty in case someone has invoked
988*c53c97f7SRobert Mustacchi * status=progress
989*c53c97f7SRobert Mustacchi */
990*c53c97f7SRobert Mustacchi if (isatty(STDERR_FILENO) == 1) {
991*c53c97f7SRobert Mustacchi stderr_tty = B_TRUE;
992*c53c97f7SRobert Mustacchi }
993*c53c97f7SRobert Mustacchi
9947c478bd9Sstevel@tonic-gate /* Skip input blocks */
9957c478bd9Sstevel@tonic-gate
996b928ac84SToomas Soome while (skip) {
997c232df92SToomas Soome ibc = iread(ibf, (char *)ibuf, ibs);
998b928ac84SToomas Soome if (ibc == (unsigned)-1) {
999b928ac84SToomas Soome if (++nbad > BADLIMIT) {
10007c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s\n",
10017c478bd9Sstevel@tonic-gate gettext("skip failed"));
10027c478bd9Sstevel@tonic-gate exit(2);
1003b928ac84SToomas Soome } else {
10047c478bd9Sstevel@tonic-gate perror("read");
10057c478bd9Sstevel@tonic-gate }
1006b928ac84SToomas Soome } else {
1007b928ac84SToomas Soome if (ibc == 0) {
10087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s\n",
10097c478bd9Sstevel@tonic-gate gettext("cannot skip past end-of-file"));
10107c478bd9Sstevel@tonic-gate exit(3);
1011b928ac84SToomas Soome } else {
10127c478bd9Sstevel@tonic-gate nbad = 0;
10137c478bd9Sstevel@tonic-gate }
10147c478bd9Sstevel@tonic-gate }
10157c478bd9Sstevel@tonic-gate skip--;
10167c478bd9Sstevel@tonic-gate }
10177c478bd9Sstevel@tonic-gate
10187c478bd9Sstevel@tonic-gate /* Seek past input blocks */
10197c478bd9Sstevel@tonic-gate
1020b928ac84SToomas Soome if (iseekn && lseek(ibf, (((off_t)iseekn) * ((off_t)ibs)), 1) == -1) {
10217c478bd9Sstevel@tonic-gate perror("lseek");
10227c478bd9Sstevel@tonic-gate exit(2);
10237c478bd9Sstevel@tonic-gate }
10247c478bd9Sstevel@tonic-gate
10257c478bd9Sstevel@tonic-gate /* Seek past output blocks */
10267c478bd9Sstevel@tonic-gate
1027b928ac84SToomas Soome if (oseekn && lseek(obf, (((off_t)oseekn) * ((off_t)obs)), 1) == -1) {
10287c478bd9Sstevel@tonic-gate perror("lseek");
10297c478bd9Sstevel@tonic-gate exit(2);
10307c478bd9Sstevel@tonic-gate }
10317c478bd9Sstevel@tonic-gate
10327c478bd9Sstevel@tonic-gate /* Initialize all buffer pointers */
10337c478bd9Sstevel@tonic-gate
10347c478bd9Sstevel@tonic-gate skipf = 0; /* not skipping an input line */
10357c478bd9Sstevel@tonic-gate ibc = 0; /* no input characters yet */
10367c478bd9Sstevel@tonic-gate obc = 0; /* no output characters yet */
10377c478bd9Sstevel@tonic-gate cbc = 0; /* the conversion buffer is empty */
10387c478bd9Sstevel@tonic-gate op = obuf; /* point to the output buffer */
10397c478bd9Sstevel@tonic-gate
10407c478bd9Sstevel@tonic-gate /* Read and convert input blocks until end of file(s) */
10417c478bd9Sstevel@tonic-gate
104219d32b9aSRobert Mustacchi /* Grab our start time for siginfo purposes */
104319d32b9aSRobert Mustacchi startt = gethrtime();
104419d32b9aSRobert Mustacchi
1045b928ac84SToomas Soome for (;;) {
1046*c53c97f7SRobert Mustacchi /*
1047*c53c97f7SRobert Mustacchi * Always call into the stats function which will check for
1048*c53c97f7SRobert Mustacchi * siginfo and related processing that needs to happen.
1049*c53c97f7SRobert Mustacchi */
1050*c53c97f7SRobert Mustacchi stats(B_TRUE);
105119d32b9aSRobert Mustacchi
1052e3bee069SRobert Mustacchi if ((count == 0 && ecount == B_FALSE) || (nifr+nipr < count)) {
10537c478bd9Sstevel@tonic-gate /* If proceed on error is enabled, zero the input buffer */
10547c478bd9Sstevel@tonic-gate
1055b928ac84SToomas Soome if (cflag & NERR) {
10567c478bd9Sstevel@tonic-gate ip = ibuf + ibs;
10577c478bd9Sstevel@tonic-gate c = ibs;
10587c478bd9Sstevel@tonic-gate if (c & 1) /* if the size is odd, */
10597c478bd9Sstevel@tonic-gate {
10607c478bd9Sstevel@tonic-gate *--ip = 0; /* clear the odd byte */
10617c478bd9Sstevel@tonic-gate }
10627c478bd9Sstevel@tonic-gate if (c >>= 1) /* divide by two */
10637c478bd9Sstevel@tonic-gate {
10647c478bd9Sstevel@tonic-gate do { /* clear two at a time */
10657c478bd9Sstevel@tonic-gate *--ip = 0;
10667c478bd9Sstevel@tonic-gate *--ip = 0;
10677c478bd9Sstevel@tonic-gate } while (--c);
10687c478bd9Sstevel@tonic-gate }
10697c478bd9Sstevel@tonic-gate }
10707c478bd9Sstevel@tonic-gate
10717c478bd9Sstevel@tonic-gate /* Read the next input block */
10727c478bd9Sstevel@tonic-gate
1073c232df92SToomas Soome ibc = iread(ibf, (char *)ibuf, ibs);
10747c478bd9Sstevel@tonic-gate
107561304e4fSPaul Dagnelie if (istriden > 0 && lseek(ibf, istriden * ((off_t)ibs),
107661304e4fSPaul Dagnelie SEEK_CUR) == -1) {
107761304e4fSPaul Dagnelie perror("lseek");
107861304e4fSPaul Dagnelie exit(2);
107961304e4fSPaul Dagnelie }
108061304e4fSPaul Dagnelie
10817c478bd9Sstevel@tonic-gate /* Process input errors */
10827c478bd9Sstevel@tonic-gate
1083b928ac84SToomas Soome if (ibc == (unsigned)-1) {
10847c478bd9Sstevel@tonic-gate perror("read");
1085b928ac84SToomas Soome if (((cflag & NERR) == 0) ||
1086b928ac84SToomas Soome (++nbad > BADLIMIT)) {
1087b928ac84SToomas Soome while (obc) {
10887c478bd9Sstevel@tonic-gate (void) flsh();
10897c478bd9Sstevel@tonic-gate }
10907c478bd9Sstevel@tonic-gate term(2);
1091b928ac84SToomas Soome } else {
1092*c53c97f7SRobert Mustacchi stats(B_FALSE);
10937c478bd9Sstevel@tonic-gate ibc = ibs; /* assume a full block */
10947c478bd9Sstevel@tonic-gate }
1095b928ac84SToomas Soome } else {
10967c478bd9Sstevel@tonic-gate nbad = 0;
10977c478bd9Sstevel@tonic-gate }
1098b928ac84SToomas Soome } else {
10997c478bd9Sstevel@tonic-gate /* Record count satisfied, simulate end of file */
11007c478bd9Sstevel@tonic-gate ibc = 0;
11017c478bd9Sstevel@tonic-gate files = 1;
11027c478bd9Sstevel@tonic-gate }
11037c478bd9Sstevel@tonic-gate
11047c478bd9Sstevel@tonic-gate /* Process end of file */
11057c478bd9Sstevel@tonic-gate
1106b928ac84SToomas Soome if (ibc == 0) {
1107b928ac84SToomas Soome switch (conv) {
11087c478bd9Sstevel@tonic-gate case UNBLOCK:
11097c478bd9Sstevel@tonic-gate case LCUNBLOCK:
11107c478bd9Sstevel@tonic-gate case UCUNBLOCK:
11117c478bd9Sstevel@tonic-gate case ASCII:
11127c478bd9Sstevel@tonic-gate case LCASCII:
11137c478bd9Sstevel@tonic-gate case UCASCII:
11147c478bd9Sstevel@tonic-gate
11157c478bd9Sstevel@tonic-gate /* Trim trailing blanks from the last line */
11167c478bd9Sstevel@tonic-gate
1117b928ac84SToomas Soome if ((c = cbc) != 0) {
11187c478bd9Sstevel@tonic-gate do {
1119b928ac84SToomas Soome if ((*--op) != ' ') {
11207c478bd9Sstevel@tonic-gate op++;
11217c478bd9Sstevel@tonic-gate break;
11227c478bd9Sstevel@tonic-gate }
11237c478bd9Sstevel@tonic-gate } while (--c);
11247c478bd9Sstevel@tonic-gate *op++ = '\n';
11257c478bd9Sstevel@tonic-gate obc -= cbc - c - 1;
11267c478bd9Sstevel@tonic-gate cbc = 0;
11277c478bd9Sstevel@tonic-gate
11287c478bd9Sstevel@tonic-gate /* Flush the output buffer if full */
11297c478bd9Sstevel@tonic-gate
1130b928ac84SToomas Soome while (obc >= obs) {
11317c478bd9Sstevel@tonic-gate op = flsh();
11327c478bd9Sstevel@tonic-gate }
11337c478bd9Sstevel@tonic-gate }
11347c478bd9Sstevel@tonic-gate break;
11357c478bd9Sstevel@tonic-gate
11367c478bd9Sstevel@tonic-gate case BLOCK:
11377c478bd9Sstevel@tonic-gate case LCBLOCK:
11387c478bd9Sstevel@tonic-gate case UCBLOCK:
11397c478bd9Sstevel@tonic-gate case EBCDIC:
11407c478bd9Sstevel@tonic-gate case LCEBCDIC:
11417c478bd9Sstevel@tonic-gate case UCEBCDIC:
11427c478bd9Sstevel@tonic-gate case IBM:
11437c478bd9Sstevel@tonic-gate case LCIBM:
11447c478bd9Sstevel@tonic-gate case UCIBM:
11457c478bd9Sstevel@tonic-gate
11467c478bd9Sstevel@tonic-gate /* Pad trailing blanks if the last line is short */
11477c478bd9Sstevel@tonic-gate
1148b928ac84SToomas Soome if (cbc) {
11497c478bd9Sstevel@tonic-gate obc += c = cbs - cbc;
11507c478bd9Sstevel@tonic-gate cbc = 0;
1151b928ac84SToomas Soome if (c > 0) {
11527c478bd9Sstevel@tonic-gate /* Use the right kind of blank */
11537c478bd9Sstevel@tonic-gate
1154b928ac84SToomas Soome switch (conv) {
11557c478bd9Sstevel@tonic-gate case BLOCK:
11567c478bd9Sstevel@tonic-gate case LCBLOCK:
11577c478bd9Sstevel@tonic-gate case UCBLOCK:
11587c478bd9Sstevel@tonic-gate ic = ' ';
11597c478bd9Sstevel@tonic-gate break;
11607c478bd9Sstevel@tonic-gate
11617c478bd9Sstevel@tonic-gate case EBCDIC:
11627c478bd9Sstevel@tonic-gate case LCEBCDIC:
11637c478bd9Sstevel@tonic-gate case UCEBCDIC:
11647c478bd9Sstevel@tonic-gate ic = atoe[' '];
11657c478bd9Sstevel@tonic-gate break;
11667c478bd9Sstevel@tonic-gate
11677c478bd9Sstevel@tonic-gate case IBM:
11687c478bd9Sstevel@tonic-gate case LCIBM:
11697c478bd9Sstevel@tonic-gate case UCIBM:
11707c478bd9Sstevel@tonic-gate ic = atoibm[' '];
11717c478bd9Sstevel@tonic-gate break;
11727c478bd9Sstevel@tonic-gate }
11737c478bd9Sstevel@tonic-gate
11747c478bd9Sstevel@tonic-gate /* Pad with trailing blanks */
11757c478bd9Sstevel@tonic-gate
11767c478bd9Sstevel@tonic-gate do {
11777c478bd9Sstevel@tonic-gate *op++ = ic;
11787c478bd9Sstevel@tonic-gate } while (--c);
11797c478bd9Sstevel@tonic-gate }
11807c478bd9Sstevel@tonic-gate }
11817c478bd9Sstevel@tonic-gate
11827c478bd9Sstevel@tonic-gate
11837c478bd9Sstevel@tonic-gate /* Flush the output buffer if full */
11847c478bd9Sstevel@tonic-gate
1185b928ac84SToomas Soome while (obc >= obs) {
11867c478bd9Sstevel@tonic-gate op = flsh();
11877c478bd9Sstevel@tonic-gate }
11887c478bd9Sstevel@tonic-gate break;
11897c478bd9Sstevel@tonic-gate }
11907c478bd9Sstevel@tonic-gate
11917c478bd9Sstevel@tonic-gate /* If no more files to read, flush the output buffer */
11927c478bd9Sstevel@tonic-gate
1193b928ac84SToomas Soome if (--files <= 0) {
11947c478bd9Sstevel@tonic-gate (void) flsh();
1195b928ac84SToomas Soome if ((close(obf) != 0) ||
1196b928ac84SToomas Soome (fclose(stdout) != 0)) {
11977c478bd9Sstevel@tonic-gate perror(gettext("dd: close error"));
11987c478bd9Sstevel@tonic-gate exit(2);
11997c478bd9Sstevel@tonic-gate }
12007c478bd9Sstevel@tonic-gate term(0); /* successful exit */
1201b928ac84SToomas Soome } else {
12027c478bd9Sstevel@tonic-gate continue; /* read the next file */
12037c478bd9Sstevel@tonic-gate }
1204b928ac84SToomas Soome } else if (ibc == ibs) {
12057c478bd9Sstevel@tonic-gate /* Normal read, check for special cases */
12067c478bd9Sstevel@tonic-gate nifr++; /* count another full input record */
1207b928ac84SToomas Soome } else {
12087c478bd9Sstevel@tonic-gate nipr++; /* count a partial input record */
12097c478bd9Sstevel@tonic-gate
12107c478bd9Sstevel@tonic-gate /* If `sync' enabled, pad nulls */
12117c478bd9Sstevel@tonic-gate
1212b928ac84SToomas Soome if ((cflag & SYNC) && ((cflag & NERR) == 0)) {
12137c478bd9Sstevel@tonic-gate c = ibs - ibc;
12147c478bd9Sstevel@tonic-gate ip = ibuf + ibs;
12157c478bd9Sstevel@tonic-gate do {
1216b928ac84SToomas Soome if ((conv == BLOCK) ||
1217b928ac84SToomas Soome (conv == UNBLOCK))
12187c478bd9Sstevel@tonic-gate *--ip = ' ';
12197c478bd9Sstevel@tonic-gate else
12207c478bd9Sstevel@tonic-gate *--ip = '\0';
12217c478bd9Sstevel@tonic-gate } while (--c);
12227c478bd9Sstevel@tonic-gate ibc = ibs;
12237c478bd9Sstevel@tonic-gate }
12247c478bd9Sstevel@tonic-gate }
12257c478bd9Sstevel@tonic-gate
12267c478bd9Sstevel@tonic-gate /* Swap the bytes in the input buffer if necessary */
12277c478bd9Sstevel@tonic-gate
1228b928ac84SToomas Soome if (cflag & SWAB) {
12297c478bd9Sstevel@tonic-gate ip = ibuf;
1230b928ac84SToomas Soome if (ibc & 1) { /* if the byte count is odd, */
12317c478bd9Sstevel@tonic-gate ip[ibc] = 0; /* make it even, pad with zero */
12327c478bd9Sstevel@tonic-gate }
12337c478bd9Sstevel@tonic-gate c = ibc >> 1; /* compute the pair count */
12347c478bd9Sstevel@tonic-gate do {
12357c478bd9Sstevel@tonic-gate ic = *ip++;
12367c478bd9Sstevel@tonic-gate ip[-1] = *ip;
12377c478bd9Sstevel@tonic-gate *ip++ = ic;
12387c478bd9Sstevel@tonic-gate } while (--c); /* do two bytes at a time */
12397c478bd9Sstevel@tonic-gate }
12407c478bd9Sstevel@tonic-gate
12417c478bd9Sstevel@tonic-gate /* Select the appropriate conversion loop */
12427c478bd9Sstevel@tonic-gate
12437c478bd9Sstevel@tonic-gate ip = ibuf;
1244b928ac84SToomas Soome switch (conv) {
12457c478bd9Sstevel@tonic-gate
12467c478bd9Sstevel@tonic-gate /* Simple copy: no conversion, preserve the input block size */
12477c478bd9Sstevel@tonic-gate
12487c478bd9Sstevel@tonic-gate case COPY:
12497c478bd9Sstevel@tonic-gate obc = ibc;
12507c478bd9Sstevel@tonic-gate (void) flsh();
12517c478bd9Sstevel@tonic-gate break;
12527c478bd9Sstevel@tonic-gate
12537c478bd9Sstevel@tonic-gate /* Simple copy: pack all output into equal sized blocks */
12547c478bd9Sstevel@tonic-gate
12557c478bd9Sstevel@tonic-gate case REBLOCK:
12567c478bd9Sstevel@tonic-gate case LCREBLOCK:
12577c478bd9Sstevel@tonic-gate case UCREBLOCK:
12587c478bd9Sstevel@tonic-gate case NBASCII:
12597c478bd9Sstevel@tonic-gate case LCNBASCII:
12607c478bd9Sstevel@tonic-gate case UCNBASCII:
12617c478bd9Sstevel@tonic-gate case NBEBCDIC:
12627c478bd9Sstevel@tonic-gate case LCNBEBCDIC:
12637c478bd9Sstevel@tonic-gate case UCNBEBCDIC:
12647c478bd9Sstevel@tonic-gate case NBIBM:
12657c478bd9Sstevel@tonic-gate case LCNBIBM:
12667c478bd9Sstevel@tonic-gate case UCNBIBM:
1267b928ac84SToomas Soome while ((c = ibc) != 0) {
1268b928ac84SToomas Soome if (c > (obs - obc)) {
12697c478bd9Sstevel@tonic-gate c = obs - obc;
12707c478bd9Sstevel@tonic-gate }
12717c478bd9Sstevel@tonic-gate ibc -= c;
12727c478bd9Sstevel@tonic-gate obc += c;
1273b928ac84SToomas Soome switch (conv) {
12747c478bd9Sstevel@tonic-gate case REBLOCK:
12757c478bd9Sstevel@tonic-gate do {
12767c478bd9Sstevel@tonic-gate *op++ = *ip++;
12777c478bd9Sstevel@tonic-gate } while (--c);
12787c478bd9Sstevel@tonic-gate break;
12797c478bd9Sstevel@tonic-gate
12807c478bd9Sstevel@tonic-gate case LCREBLOCK:
12817c478bd9Sstevel@tonic-gate do {
12827c478bd9Sstevel@tonic-gate *op++ = utol[*ip++];
12837c478bd9Sstevel@tonic-gate } while (--c);
12847c478bd9Sstevel@tonic-gate break;
12857c478bd9Sstevel@tonic-gate
12867c478bd9Sstevel@tonic-gate case UCREBLOCK:
12877c478bd9Sstevel@tonic-gate do {
12887c478bd9Sstevel@tonic-gate *op++ = ltou[*ip++];
12897c478bd9Sstevel@tonic-gate } while (--c);
12907c478bd9Sstevel@tonic-gate break;
12917c478bd9Sstevel@tonic-gate
12927c478bd9Sstevel@tonic-gate case NBASCII:
12937c478bd9Sstevel@tonic-gate do {
12947c478bd9Sstevel@tonic-gate *op++ = etoa[*ip++];
12957c478bd9Sstevel@tonic-gate } while (--c);
12967c478bd9Sstevel@tonic-gate break;
12977c478bd9Sstevel@tonic-gate
12987c478bd9Sstevel@tonic-gate case LCNBASCII:
12997c478bd9Sstevel@tonic-gate do {
13007c478bd9Sstevel@tonic-gate *op++ = utol[etoa[*ip++]];
13017c478bd9Sstevel@tonic-gate } while (--c);
13027c478bd9Sstevel@tonic-gate break;
13037c478bd9Sstevel@tonic-gate
13047c478bd9Sstevel@tonic-gate case UCNBASCII:
13057c478bd9Sstevel@tonic-gate do {
13067c478bd9Sstevel@tonic-gate *op++ = ltou[etoa[*ip++]];
13077c478bd9Sstevel@tonic-gate } while (--c);
13087c478bd9Sstevel@tonic-gate break;
13097c478bd9Sstevel@tonic-gate
13107c478bd9Sstevel@tonic-gate case NBEBCDIC:
13117c478bd9Sstevel@tonic-gate do {
13127c478bd9Sstevel@tonic-gate *op++ = atoe[*ip++];
13137c478bd9Sstevel@tonic-gate } while (--c);
13147c478bd9Sstevel@tonic-gate break;
13157c478bd9Sstevel@tonic-gate
13167c478bd9Sstevel@tonic-gate case LCNBEBCDIC:
13177c478bd9Sstevel@tonic-gate do {
13187c478bd9Sstevel@tonic-gate *op++ = atoe[utol[*ip++]];
13197c478bd9Sstevel@tonic-gate } while (--c);
13207c478bd9Sstevel@tonic-gate break;
13217c478bd9Sstevel@tonic-gate
13227c478bd9Sstevel@tonic-gate case UCNBEBCDIC:
13237c478bd9Sstevel@tonic-gate do {
13247c478bd9Sstevel@tonic-gate *op++ = atoe[ltou[*ip++]];
13257c478bd9Sstevel@tonic-gate } while (--c);
13267c478bd9Sstevel@tonic-gate break;
13277c478bd9Sstevel@tonic-gate
13287c478bd9Sstevel@tonic-gate case NBIBM:
13297c478bd9Sstevel@tonic-gate do {
13307c478bd9Sstevel@tonic-gate *op++ = atoibm[*ip++];
13317c478bd9Sstevel@tonic-gate } while (--c);
13327c478bd9Sstevel@tonic-gate break;
13337c478bd9Sstevel@tonic-gate
13347c478bd9Sstevel@tonic-gate case LCNBIBM:
13357c478bd9Sstevel@tonic-gate do {
13367c478bd9Sstevel@tonic-gate *op++ = atoibm[utol[*ip++]];
13377c478bd9Sstevel@tonic-gate } while (--c);
13387c478bd9Sstevel@tonic-gate break;
13397c478bd9Sstevel@tonic-gate
13407c478bd9Sstevel@tonic-gate case UCNBIBM:
13417c478bd9Sstevel@tonic-gate do {
13427c478bd9Sstevel@tonic-gate *op++ = atoibm[ltou[*ip++]];
13437c478bd9Sstevel@tonic-gate } while (--c);
13447c478bd9Sstevel@tonic-gate break;
13457c478bd9Sstevel@tonic-gate }
1346b928ac84SToomas Soome if (obc >= obs) {
13477c478bd9Sstevel@tonic-gate op = flsh();
13487c478bd9Sstevel@tonic-gate }
13497c478bd9Sstevel@tonic-gate }
13507c478bd9Sstevel@tonic-gate break;
13517c478bd9Sstevel@tonic-gate
13527c478bd9Sstevel@tonic-gate /* Convert from blocked records to lines terminated by newline */
13537c478bd9Sstevel@tonic-gate
13547c478bd9Sstevel@tonic-gate case UNBLOCK:
13557c478bd9Sstevel@tonic-gate case LCUNBLOCK:
13567c478bd9Sstevel@tonic-gate case UCUNBLOCK:
13577c478bd9Sstevel@tonic-gate case ASCII:
13587c478bd9Sstevel@tonic-gate case LCASCII:
13597c478bd9Sstevel@tonic-gate case UCASCII:
1360b928ac84SToomas Soome while ((c = ibc) != 0) {
1361b928ac84SToomas Soome if (c > (cbs - cbc)) {
13627c478bd9Sstevel@tonic-gate /* if more than one record, */
13637c478bd9Sstevel@tonic-gate c = cbs - cbc;
13647c478bd9Sstevel@tonic-gate /* only copy one record */
13657c478bd9Sstevel@tonic-gate }
13667c478bd9Sstevel@tonic-gate ibc -= c;
13677c478bd9Sstevel@tonic-gate cbc += c;
13687c478bd9Sstevel@tonic-gate obc += c;
1369b928ac84SToomas Soome switch (conv) {
13707c478bd9Sstevel@tonic-gate case UNBLOCK:
13717c478bd9Sstevel@tonic-gate do {
13727c478bd9Sstevel@tonic-gate *op++ = *ip++;
13737c478bd9Sstevel@tonic-gate } while (--c);
13747c478bd9Sstevel@tonic-gate break;
13757c478bd9Sstevel@tonic-gate
13767c478bd9Sstevel@tonic-gate case LCUNBLOCK:
13777c478bd9Sstevel@tonic-gate do {
13787c478bd9Sstevel@tonic-gate *op++ = utol[*ip++];
13797c478bd9Sstevel@tonic-gate } while (--c);
13807c478bd9Sstevel@tonic-gate break;
13817c478bd9Sstevel@tonic-gate
13827c478bd9Sstevel@tonic-gate case UCUNBLOCK:
13837c478bd9Sstevel@tonic-gate do {
13847c478bd9Sstevel@tonic-gate *op++ = ltou[*ip++];
13857c478bd9Sstevel@tonic-gate } while (--c);
13867c478bd9Sstevel@tonic-gate break;
13877c478bd9Sstevel@tonic-gate
13887c478bd9Sstevel@tonic-gate case ASCII:
13897c478bd9Sstevel@tonic-gate do {
13907c478bd9Sstevel@tonic-gate *op++ = etoa[*ip++];
13917c478bd9Sstevel@tonic-gate } while (--c);
13927c478bd9Sstevel@tonic-gate break;
13937c478bd9Sstevel@tonic-gate
13947c478bd9Sstevel@tonic-gate case LCASCII:
13957c478bd9Sstevel@tonic-gate do {
13967c478bd9Sstevel@tonic-gate *op++ = utol[etoa[*ip++]];
13977c478bd9Sstevel@tonic-gate } while (--c);
13987c478bd9Sstevel@tonic-gate break;
13997c478bd9Sstevel@tonic-gate
14007c478bd9Sstevel@tonic-gate case UCASCII:
14017c478bd9Sstevel@tonic-gate do {
14027c478bd9Sstevel@tonic-gate *op++ = ltou[etoa[*ip++]];
14037c478bd9Sstevel@tonic-gate } while (--c);
14047c478bd9Sstevel@tonic-gate break;
14057c478bd9Sstevel@tonic-gate }
14067c478bd9Sstevel@tonic-gate
14077c478bd9Sstevel@tonic-gate /* Trim trailing blanks if the line is full */
14087c478bd9Sstevel@tonic-gate
1409b928ac84SToomas Soome if (cbc == cbs) {
14107c478bd9Sstevel@tonic-gate c = cbs; /* `do - while' is usually */
14117c478bd9Sstevel@tonic-gate do { /* faster than `for' */
1412b928ac84SToomas Soome if ((*--op) != ' ') {
14137c478bd9Sstevel@tonic-gate op++;
14147c478bd9Sstevel@tonic-gate break;
14157c478bd9Sstevel@tonic-gate }
14167c478bd9Sstevel@tonic-gate } while (--c);
14177c478bd9Sstevel@tonic-gate *op++ = '\n';
14187c478bd9Sstevel@tonic-gate obc -= cbs - c - 1;
14197c478bd9Sstevel@tonic-gate cbc = 0;
14207c478bd9Sstevel@tonic-gate
14217c478bd9Sstevel@tonic-gate /* Flush the output buffer if full */
14227c478bd9Sstevel@tonic-gate
1423b928ac84SToomas Soome while (obc >= obs) {
14247c478bd9Sstevel@tonic-gate op = flsh();
14257c478bd9Sstevel@tonic-gate }
14267c478bd9Sstevel@tonic-gate }
14277c478bd9Sstevel@tonic-gate }
14287c478bd9Sstevel@tonic-gate break;
14297c478bd9Sstevel@tonic-gate
14307c478bd9Sstevel@tonic-gate /* Convert to blocked records */
14317c478bd9Sstevel@tonic-gate
14327c478bd9Sstevel@tonic-gate case BLOCK:
14337c478bd9Sstevel@tonic-gate case LCBLOCK:
14347c478bd9Sstevel@tonic-gate case UCBLOCK:
14357c478bd9Sstevel@tonic-gate case EBCDIC:
14367c478bd9Sstevel@tonic-gate case LCEBCDIC:
14377c478bd9Sstevel@tonic-gate case UCEBCDIC:
14387c478bd9Sstevel@tonic-gate case IBM:
14397c478bd9Sstevel@tonic-gate case LCIBM:
14407c478bd9Sstevel@tonic-gate case UCIBM:
1441b928ac84SToomas Soome while ((c = ibc) != 0) {
14427c478bd9Sstevel@tonic-gate int nlflag = 0;
14437c478bd9Sstevel@tonic-gate
1444b928ac84SToomas Soome /*
1445b928ac84SToomas Soome * We may have to skip to the end of a long
1446b928ac84SToomas Soome * line.
1447b928ac84SToomas Soome */
14487c478bd9Sstevel@tonic-gate
1449b928ac84SToomas Soome if (skipf) {
14507c478bd9Sstevel@tonic-gate do {
1451b928ac84SToomas Soome if ((ic = *ip++) == '\n') {
14527c478bd9Sstevel@tonic-gate skipf = 0;
14537c478bd9Sstevel@tonic-gate c--;
14547c478bd9Sstevel@tonic-gate break;
14557c478bd9Sstevel@tonic-gate }
14567c478bd9Sstevel@tonic-gate } while (--c);
1457b928ac84SToomas Soome if ((ibc = c) == 0) {
14587c478bd9Sstevel@tonic-gate continue;
14597c478bd9Sstevel@tonic-gate /* read another block */
14607c478bd9Sstevel@tonic-gate }
14617c478bd9Sstevel@tonic-gate }
14627c478bd9Sstevel@tonic-gate
14637c478bd9Sstevel@tonic-gate /* If anything left, copy until newline */
14647c478bd9Sstevel@tonic-gate
1465b928ac84SToomas Soome if (c > (cbs - cbc + 1)) {
14667c478bd9Sstevel@tonic-gate c = cbs - cbc + 1;
14677c478bd9Sstevel@tonic-gate }
14687c478bd9Sstevel@tonic-gate ibc -= c;
14697c478bd9Sstevel@tonic-gate cbc += c;
14707c478bd9Sstevel@tonic-gate obc += c;
14717c478bd9Sstevel@tonic-gate
1472b928ac84SToomas Soome switch (conv) {
14737c478bd9Sstevel@tonic-gate case BLOCK:
14747c478bd9Sstevel@tonic-gate do {
1475b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
14767c478bd9Sstevel@tonic-gate *op++ = ic;
1477b928ac84SToomas Soome } else {
14787c478bd9Sstevel@tonic-gate nlflag = 1;
14797c478bd9Sstevel@tonic-gate break;
14807c478bd9Sstevel@tonic-gate }
14817c478bd9Sstevel@tonic-gate } while (--c);
14827c478bd9Sstevel@tonic-gate break;
14837c478bd9Sstevel@tonic-gate
14847c478bd9Sstevel@tonic-gate case LCBLOCK:
14857c478bd9Sstevel@tonic-gate do {
1486b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
14877c478bd9Sstevel@tonic-gate *op++ = utol[ic];
1488b928ac84SToomas Soome } else {
14897c478bd9Sstevel@tonic-gate nlflag = 1;
14907c478bd9Sstevel@tonic-gate break;
14917c478bd9Sstevel@tonic-gate }
14927c478bd9Sstevel@tonic-gate } while (--c);
14937c478bd9Sstevel@tonic-gate break;
14947c478bd9Sstevel@tonic-gate
14957c478bd9Sstevel@tonic-gate case UCBLOCK:
14967c478bd9Sstevel@tonic-gate do {
1497b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
14987c478bd9Sstevel@tonic-gate *op++ = ltou[ic];
1499b928ac84SToomas Soome } else {
15007c478bd9Sstevel@tonic-gate nlflag = 1;
15017c478bd9Sstevel@tonic-gate break;
15027c478bd9Sstevel@tonic-gate }
15037c478bd9Sstevel@tonic-gate } while (--c);
15047c478bd9Sstevel@tonic-gate break;
15057c478bd9Sstevel@tonic-gate
15067c478bd9Sstevel@tonic-gate case EBCDIC:
15077c478bd9Sstevel@tonic-gate do {
1508b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
15097c478bd9Sstevel@tonic-gate *op++ = atoe[ic];
1510b928ac84SToomas Soome } else {
15117c478bd9Sstevel@tonic-gate nlflag = 1;
15127c478bd9Sstevel@tonic-gate break;
15137c478bd9Sstevel@tonic-gate }
15147c478bd9Sstevel@tonic-gate } while (--c);
15157c478bd9Sstevel@tonic-gate break;
15167c478bd9Sstevel@tonic-gate
15177c478bd9Sstevel@tonic-gate case LCEBCDIC:
15187c478bd9Sstevel@tonic-gate do {
1519b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
15207c478bd9Sstevel@tonic-gate *op++ = atoe[utol[ic]];
1521b928ac84SToomas Soome } else {
15227c478bd9Sstevel@tonic-gate nlflag = 1;
15237c478bd9Sstevel@tonic-gate break;
15247c478bd9Sstevel@tonic-gate }
15257c478bd9Sstevel@tonic-gate } while (--c);
15267c478bd9Sstevel@tonic-gate break;
15277c478bd9Sstevel@tonic-gate
15287c478bd9Sstevel@tonic-gate case UCEBCDIC:
15297c478bd9Sstevel@tonic-gate do {
1530b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
15317c478bd9Sstevel@tonic-gate *op++ = atoe[ltou[ic]];
1532b928ac84SToomas Soome } else {
15337c478bd9Sstevel@tonic-gate nlflag = 1;
15347c478bd9Sstevel@tonic-gate break;
15357c478bd9Sstevel@tonic-gate }
15367c478bd9Sstevel@tonic-gate } while (--c);
15377c478bd9Sstevel@tonic-gate break;
15387c478bd9Sstevel@tonic-gate
15397c478bd9Sstevel@tonic-gate case IBM:
15407c478bd9Sstevel@tonic-gate do {
1541b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
15427c478bd9Sstevel@tonic-gate *op++ = atoibm[ic];
1543b928ac84SToomas Soome } else {
15447c478bd9Sstevel@tonic-gate nlflag = 1;
15457c478bd9Sstevel@tonic-gate break;
15467c478bd9Sstevel@tonic-gate }
15477c478bd9Sstevel@tonic-gate } while (--c);
15487c478bd9Sstevel@tonic-gate break;
15497c478bd9Sstevel@tonic-gate
15507c478bd9Sstevel@tonic-gate case LCIBM:
15517c478bd9Sstevel@tonic-gate do {
1552b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
1553b928ac84SToomas Soome *op++ =
1554b928ac84SToomas Soome atoibm[utol[ic]];
1555b928ac84SToomas Soome } else {
15567c478bd9Sstevel@tonic-gate nlflag = 1;
15577c478bd9Sstevel@tonic-gate break;
15587c478bd9Sstevel@tonic-gate }
15597c478bd9Sstevel@tonic-gate } while (--c);
15607c478bd9Sstevel@tonic-gate break;
15617c478bd9Sstevel@tonic-gate
15627c478bd9Sstevel@tonic-gate case UCIBM:
15637c478bd9Sstevel@tonic-gate do {
1564b928ac84SToomas Soome if ((ic = *ip++) != '\n') {
1565b928ac84SToomas Soome *op++ =
1566b928ac84SToomas Soome atoibm[ltou[ic]];
1567b928ac84SToomas Soome } else {
15687c478bd9Sstevel@tonic-gate nlflag = 1;
15697c478bd9Sstevel@tonic-gate break;
15707c478bd9Sstevel@tonic-gate }
15717c478bd9Sstevel@tonic-gate } while (--c);
15727c478bd9Sstevel@tonic-gate break;
15737c478bd9Sstevel@tonic-gate }
15747c478bd9Sstevel@tonic-gate
15757c478bd9Sstevel@tonic-gate /* If newline found, update all the counters and */
15767c478bd9Sstevel@tonic-gate /* pointers, pad with trailing blanks if necessary */
15777c478bd9Sstevel@tonic-gate
1578b928ac84SToomas Soome if (nlflag) {
15797c478bd9Sstevel@tonic-gate ibc += c - 1;
15807c478bd9Sstevel@tonic-gate obc += cbs - cbc;
15817c478bd9Sstevel@tonic-gate c += cbs - cbc;
15827c478bd9Sstevel@tonic-gate cbc = 0;
1583b928ac84SToomas Soome if (c > 0) {
15847c478bd9Sstevel@tonic-gate /* Use the right kind of blank */
15857c478bd9Sstevel@tonic-gate
1586b928ac84SToomas Soome switch (conv) {
15877c478bd9Sstevel@tonic-gate case BLOCK:
15887c478bd9Sstevel@tonic-gate case LCBLOCK:
15897c478bd9Sstevel@tonic-gate case UCBLOCK:
15907c478bd9Sstevel@tonic-gate ic = ' ';
15917c478bd9Sstevel@tonic-gate break;
15927c478bd9Sstevel@tonic-gate
15937c478bd9Sstevel@tonic-gate case EBCDIC:
15947c478bd9Sstevel@tonic-gate case LCEBCDIC:
15957c478bd9Sstevel@tonic-gate case UCEBCDIC:
15967c478bd9Sstevel@tonic-gate ic = atoe[' '];
15977c478bd9Sstevel@tonic-gate break;
15987c478bd9Sstevel@tonic-gate
15997c478bd9Sstevel@tonic-gate case IBM:
16007c478bd9Sstevel@tonic-gate case LCIBM:
16017c478bd9Sstevel@tonic-gate case UCIBM:
16027c478bd9Sstevel@tonic-gate ic = atoibm[' '];
16037c478bd9Sstevel@tonic-gate break;
16047c478bd9Sstevel@tonic-gate }
16057c478bd9Sstevel@tonic-gate
16067c478bd9Sstevel@tonic-gate /* Pad with trailing blanks */
16077c478bd9Sstevel@tonic-gate
16087c478bd9Sstevel@tonic-gate do {
16097c478bd9Sstevel@tonic-gate *op++ = ic;
16107c478bd9Sstevel@tonic-gate } while (--c);
16117c478bd9Sstevel@tonic-gate }
16127c478bd9Sstevel@tonic-gate }
16137c478bd9Sstevel@tonic-gate
16147c478bd9Sstevel@tonic-gate /* If not end of line, this line may be too long */
16157c478bd9Sstevel@tonic-gate
1616b928ac84SToomas Soome else if (cbc > cbs) {
16177c478bd9Sstevel@tonic-gate skipf = 1; /* note skip in progress */
16187c478bd9Sstevel@tonic-gate obc--;
16197c478bd9Sstevel@tonic-gate op--;
16207c478bd9Sstevel@tonic-gate cbc = 0;
16217c478bd9Sstevel@tonic-gate ntrunc++; /* count another long line */
16227c478bd9Sstevel@tonic-gate }
16237c478bd9Sstevel@tonic-gate
16247c478bd9Sstevel@tonic-gate /* Flush the output buffer if full */
16257c478bd9Sstevel@tonic-gate
1626b928ac84SToomas Soome while (obc >= obs) {
16277c478bd9Sstevel@tonic-gate op = flsh();
16287c478bd9Sstevel@tonic-gate }
16297c478bd9Sstevel@tonic-gate }
16307c478bd9Sstevel@tonic-gate break;
16317c478bd9Sstevel@tonic-gate }
16327c478bd9Sstevel@tonic-gate }
1633a77d64afScf46844 /* NOTREACHED */
1634a77d64afScf46844 return (0);
16357c478bd9Sstevel@tonic-gate }
16367c478bd9Sstevel@tonic-gate
16377c478bd9Sstevel@tonic-gate /* match ************************************************************** */
16387c478bd9Sstevel@tonic-gate /* */
16397c478bd9Sstevel@tonic-gate /* Compare two text strings for equality */
16407c478bd9Sstevel@tonic-gate /* */
16417c478bd9Sstevel@tonic-gate /* Arg: s - pointer to string to match with a command arg */
16427c478bd9Sstevel@tonic-gate /* Global arg: string - pointer to command arg */
16437c478bd9Sstevel@tonic-gate /* */
16447c478bd9Sstevel@tonic-gate /* Return: 1 if match, 0 if no match */
16457c478bd9Sstevel@tonic-gate /* If match, also reset `string' to point to the text */
16467c478bd9Sstevel@tonic-gate /* that follows the matching text. */
16477c478bd9Sstevel@tonic-gate /* */
16487c478bd9Sstevel@tonic-gate /* ******************************************************************** */
16497c478bd9Sstevel@tonic-gate
16507c478bd9Sstevel@tonic-gate static int
match(char * s)1651b928ac84SToomas Soome match(char *s)
16527c478bd9Sstevel@tonic-gate {
16537c478bd9Sstevel@tonic-gate char *cs;
16547c478bd9Sstevel@tonic-gate
16557c478bd9Sstevel@tonic-gate cs = string;
1656b928ac84SToomas Soome while (*cs++ == *s) {
1657b928ac84SToomas Soome if (*s++ == '\0') {
16587c478bd9Sstevel@tonic-gate goto true;
16597c478bd9Sstevel@tonic-gate }
16607c478bd9Sstevel@tonic-gate }
1661b928ac84SToomas Soome if (*s != '\0') {
16627c478bd9Sstevel@tonic-gate return (0);
16637c478bd9Sstevel@tonic-gate }
16647c478bd9Sstevel@tonic-gate
16657c478bd9Sstevel@tonic-gate true:
16667c478bd9Sstevel@tonic-gate cs--;
16677c478bd9Sstevel@tonic-gate string = cs;
16687c478bd9Sstevel@tonic-gate return (1);
16697c478bd9Sstevel@tonic-gate }
16707c478bd9Sstevel@tonic-gate
16717c478bd9Sstevel@tonic-gate /* number ************************************************************* */
16727c478bd9Sstevel@tonic-gate /* */
16737c478bd9Sstevel@tonic-gate /* Convert a numeric arg to binary */
16747c478bd9Sstevel@tonic-gate /* */
16757c478bd9Sstevel@tonic-gate /* Arg: big - maximum valid input number */
16767c478bd9Sstevel@tonic-gate /* Global arg: string - pointer to command arg */
16777c478bd9Sstevel@tonic-gate /* */
16784cddff70SJosef 'Jeff' Sipek /* Valid forms: 123 | 123k | 123M | 123G | 123T | 123P | 123E | 123Z | */
16794cddff70SJosef 'Jeff' Sipek /* 123w | 123b | 123*123 | 123x123 */
16807c478bd9Sstevel@tonic-gate /* plus combinations such as 2b*3kw*4w */
16817c478bd9Sstevel@tonic-gate /* */
16827c478bd9Sstevel@tonic-gate /* Return: converted number */
16837c478bd9Sstevel@tonic-gate /* */
16847c478bd9Sstevel@tonic-gate /* ******************************************************************** */
16857c478bd9Sstevel@tonic-gate
16867c478bd9Sstevel@tonic-gate static unsigned long long
number(long long big)1687b928ac84SToomas Soome number(long long big)
16887c478bd9Sstevel@tonic-gate {
16897c478bd9Sstevel@tonic-gate char *cs;
16907c478bd9Sstevel@tonic-gate long long n;
16917c478bd9Sstevel@tonic-gate long long cut = BIG / 10; /* limit to avoid overflow */
16927c478bd9Sstevel@tonic-gate
16937c478bd9Sstevel@tonic-gate cs = string;
16947c478bd9Sstevel@tonic-gate n = 0;
1695b928ac84SToomas Soome while ((*cs >= '0') && (*cs <= '9') && (n <= cut)) {
16967c478bd9Sstevel@tonic-gate n = n * 10 + *cs++ - '0';
16977c478bd9Sstevel@tonic-gate }
1698b928ac84SToomas Soome for (;;) {
1699b928ac84SToomas Soome switch (*cs++) {
17007c478bd9Sstevel@tonic-gate
17014cddff70SJosef 'Jeff' Sipek case 'Z':
17024cddff70SJosef 'Jeff' Sipek n *= 1024;
17034cddff70SJosef 'Jeff' Sipek /* FALLTHROUGH */
17044cddff70SJosef 'Jeff' Sipek
17054cddff70SJosef 'Jeff' Sipek case 'E':
17064cddff70SJosef 'Jeff' Sipek n *= 1024;
17074cddff70SJosef 'Jeff' Sipek /* FALLTHROUGH */
17084cddff70SJosef 'Jeff' Sipek
17094cddff70SJosef 'Jeff' Sipek case 'P':
17104cddff70SJosef 'Jeff' Sipek n *= 1024;
17114cddff70SJosef 'Jeff' Sipek /* FALLTHROUGH */
17124cddff70SJosef 'Jeff' Sipek
17134cddff70SJosef 'Jeff' Sipek case 'T':
17144cddff70SJosef 'Jeff' Sipek n *= 1024;
17154cddff70SJosef 'Jeff' Sipek /* FALLTHROUGH */
17164cddff70SJosef 'Jeff' Sipek
17174cddff70SJosef 'Jeff' Sipek case 'G':
17184cddff70SJosef 'Jeff' Sipek n *= 1024;
17194cddff70SJosef 'Jeff' Sipek /* FALLTHROUGH */
17204cddff70SJosef 'Jeff' Sipek
17214cddff70SJosef 'Jeff' Sipek case 'M':
17224cddff70SJosef 'Jeff' Sipek n *= 1024;
17234cddff70SJosef 'Jeff' Sipek /* FALLTHROUGH */
17244cddff70SJosef 'Jeff' Sipek
17257c478bd9Sstevel@tonic-gate case 'k':
17267c478bd9Sstevel@tonic-gate n *= 1024;
17277c478bd9Sstevel@tonic-gate continue;
17287c478bd9Sstevel@tonic-gate
17297c478bd9Sstevel@tonic-gate case 'w':
17307c478bd9Sstevel@tonic-gate n *= 2;
17317c478bd9Sstevel@tonic-gate continue;
17327c478bd9Sstevel@tonic-gate
17337c478bd9Sstevel@tonic-gate case 'b':
17347c478bd9Sstevel@tonic-gate n *= BSIZE;
17357c478bd9Sstevel@tonic-gate continue;
17367c478bd9Sstevel@tonic-gate
17377c478bd9Sstevel@tonic-gate case '*':
17387c478bd9Sstevel@tonic-gate case 'x':
17397c478bd9Sstevel@tonic-gate string = cs;
17407c478bd9Sstevel@tonic-gate n *= number(BIG);
17417c478bd9Sstevel@tonic-gate
17427c478bd9Sstevel@tonic-gate /* FALLTHROUGH */
17437c478bd9Sstevel@tonic-gate /* Fall into exit test, recursion has read rest of string */
17447c478bd9Sstevel@tonic-gate /* End of string, check for a valid number */
17457c478bd9Sstevel@tonic-gate
17467c478bd9Sstevel@tonic-gate case '\0':
1747b928ac84SToomas Soome if ((n > big) || (n < 0)) {
17487c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s \"%llu\"\n",
17497c478bd9Sstevel@tonic-gate gettext("argument out of range:"), n);
17507c478bd9Sstevel@tonic-gate exit(2);
17517c478bd9Sstevel@tonic-gate }
17527c478bd9Sstevel@tonic-gate return (n);
17537c478bd9Sstevel@tonic-gate
17547c478bd9Sstevel@tonic-gate default:
17557c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "dd: %s \"%s\"\n",
17567c478bd9Sstevel@tonic-gate gettext("bad numeric argument:"), string);
17577c478bd9Sstevel@tonic-gate exit(2);
17587c478bd9Sstevel@tonic-gate }
17597c478bd9Sstevel@tonic-gate } /* never gets here */
17607c478bd9Sstevel@tonic-gate }
17617c478bd9Sstevel@tonic-gate
17627c478bd9Sstevel@tonic-gate /* flsh *************************************************************** */
17637c478bd9Sstevel@tonic-gate /* */
17647c478bd9Sstevel@tonic-gate /* Flush the output buffer, move any excess bytes down to the beginning */
17657c478bd9Sstevel@tonic-gate /* */
17667c478bd9Sstevel@tonic-gate /* Arg: none */
176761304e4fSPaul Dagnelie /* Global args: obuf, obc, obs, nofr, nopr, ostriden */
17687c478bd9Sstevel@tonic-gate /* */
17697c478bd9Sstevel@tonic-gate /* Return: Pointer to the first free byte in the output buffer. */
17707c478bd9Sstevel@tonic-gate /* Also reset `obc' to account for moved bytes. */
17717c478bd9Sstevel@tonic-gate /* */
17727c478bd9Sstevel@tonic-gate /* ******************************************************************** */
17737c478bd9Sstevel@tonic-gate
1774b928ac84SToomas Soome static unsigned char *
flsh(void)1775b928ac84SToomas Soome flsh(void)
17767c478bd9Sstevel@tonic-gate {
17777c478bd9Sstevel@tonic-gate unsigned char *op, *cp;
17787c478bd9Sstevel@tonic-gate int bc;
17797c478bd9Sstevel@tonic-gate unsigned int oc;
17807c478bd9Sstevel@tonic-gate
1781b928ac84SToomas Soome if (obc) { /* don't flush if the buffer is empty */
17827c478bd9Sstevel@tonic-gate if (obc >= obs) {
17837c478bd9Sstevel@tonic-gate oc = obs;
17847c478bd9Sstevel@tonic-gate nofr++; /* count a full output buffer */
1785b928ac84SToomas Soome } else {
17867c478bd9Sstevel@tonic-gate oc = obc;
17877c478bd9Sstevel@tonic-gate nopr++; /* count a partial output buffer */
17887c478bd9Sstevel@tonic-gate }
17897c478bd9Sstevel@tonic-gate bc = write(obf, (char *)obuf, oc);
17907c478bd9Sstevel@tonic-gate if (bc != oc) {
1791b928ac84SToomas Soome if (bc < 0) {
17927c478bd9Sstevel@tonic-gate perror("write");
1793b928ac84SToomas Soome } else {
17947c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
17957c478bd9Sstevel@tonic-gate gettext("dd: unexpected short write, "
17967c478bd9Sstevel@tonic-gate "wrote %d bytes, expected %d\n"), bc, oc);
1797b928ac84SToomas Soome }
17987c478bd9Sstevel@tonic-gate term(2);
17997c478bd9Sstevel@tonic-gate }
180061304e4fSPaul Dagnelie
180161304e4fSPaul Dagnelie if (ostriden > 0 && lseek(obf, ostriden * ((off_t)obs),
180261304e4fSPaul Dagnelie SEEK_CUR) == -1) {
180361304e4fSPaul Dagnelie perror("lseek");
180461304e4fSPaul Dagnelie exit(2);
180561304e4fSPaul Dagnelie }
180661304e4fSPaul Dagnelie
18077c478bd9Sstevel@tonic-gate obc -= oc;
18087c478bd9Sstevel@tonic-gate op = obuf;
180919d32b9aSRobert Mustacchi obytes += bc;
18107c478bd9Sstevel@tonic-gate
18117c478bd9Sstevel@tonic-gate /* If any data in the conversion buffer, move it into */
18127c478bd9Sstevel@tonic-gate /* the output buffer */
18137c478bd9Sstevel@tonic-gate
18147c478bd9Sstevel@tonic-gate if (obc) {
18157c478bd9Sstevel@tonic-gate cp = obuf + obs;
18167c478bd9Sstevel@tonic-gate bc = obc;
18177c478bd9Sstevel@tonic-gate do {
18187c478bd9Sstevel@tonic-gate *op++ = *cp++;
18197c478bd9Sstevel@tonic-gate } while (--bc);
18207c478bd9Sstevel@tonic-gate }
18217c478bd9Sstevel@tonic-gate return (op);
18227c478bd9Sstevel@tonic-gate }
18237c478bd9Sstevel@tonic-gate return (obuf);
18247c478bd9Sstevel@tonic-gate }
18257c478bd9Sstevel@tonic-gate
18267c478bd9Sstevel@tonic-gate /* term *************************************************************** */
18277c478bd9Sstevel@tonic-gate /* */
18287c478bd9Sstevel@tonic-gate /* Write record statistics, then exit */
18297c478bd9Sstevel@tonic-gate /* */
18307c478bd9Sstevel@tonic-gate /* Arg: c - exit status code */
18317c478bd9Sstevel@tonic-gate /* */
18327c478bd9Sstevel@tonic-gate /* Return: no return, calls exit */
18337c478bd9Sstevel@tonic-gate /* */
18347c478bd9Sstevel@tonic-gate /* ******************************************************************** */
18357c478bd9Sstevel@tonic-gate
18367c478bd9Sstevel@tonic-gate static void
term(int c)1837b928ac84SToomas Soome term(int c)
18387c478bd9Sstevel@tonic-gate {
1839*c53c97f7SRobert Mustacchi stats(B_FALSE);
18407c478bd9Sstevel@tonic-gate exit(c);
18417c478bd9Sstevel@tonic-gate }
18427c478bd9Sstevel@tonic-gate
18437c478bd9Sstevel@tonic-gate /* stats ************************************************************** */
18447c478bd9Sstevel@tonic-gate /* */
18457c478bd9Sstevel@tonic-gate /* Write record statistics onto standard error */
18467c478bd9Sstevel@tonic-gate /* */
1847*c53c97f7SRobert Mustacchi /* Args: main_loop - whether or not we were called from the main */
1848*c53c97f7SRobert Mustacchi /* loop and need to consider the siginfo */
1849*c53c97f7SRobert Mustacchi /* handler or status=progress output */
1850b928ac84SToomas Soome /* Global args: nifr, nipr, nofr, nopr, ntrunc, obytes */
18517c478bd9Sstevel@tonic-gate /* */
18527c478bd9Sstevel@tonic-gate /* Return: void */
18537c478bd9Sstevel@tonic-gate /* */
18547c478bd9Sstevel@tonic-gate /* ******************************************************************** */
18557c478bd9Sstevel@tonic-gate
18567c478bd9Sstevel@tonic-gate static void
stats(boolean_t main_loop)1857*c53c97f7SRobert Mustacchi stats(boolean_t main_loop)
18587c478bd9Sstevel@tonic-gate {
185919d32b9aSRobert Mustacchi hrtime_t delta = gethrtime() - startt;
186019d32b9aSRobert Mustacchi double secs = delta * 1e-9;
1861*c53c97f7SRobert Mustacchi char bps[NN_NUMBUF_SZ], hobytes[NN_NUMBUF_SZ];
1862*c53c97f7SRobert Mustacchi boolean_t is_progress = B_FALSE;
1863*c53c97f7SRobert Mustacchi const char *head = "";
1864*c53c97f7SRobert Mustacchi const char *tail = "\n";
186519d32b9aSRobert Mustacchi
1866*c53c97f7SRobert Mustacchi /*
1867*c53c97f7SRobert Mustacchi * If we've been asked to not print this, then never do.
1868*c53c97f7SRobert Mustacchi */
1869*c53c97f7SRobert Mustacchi if (status_arg == DD_STATUS_NONE) {
1870*c53c97f7SRobert Mustacchi return;
1871*c53c97f7SRobert Mustacchi }
1872*c53c97f7SRobert Mustacchi
1873*c53c97f7SRobert Mustacchi /*
1874*c53c97f7SRobert Mustacchi * If we came here from the main loop, then we need to go through and
1875*c53c97f7SRobert Mustacchi * determine if we need to do anything at all. There are two cases that
1876*c53c97f7SRobert Mustacchi * we will have to do something:
1877*c53c97f7SRobert Mustacchi *
1878*c53c97f7SRobert Mustacchi * 1) We were asked to by the siginfo handler
1879*c53c97f7SRobert Mustacchi * 2) We are here from the status=progress handler and enough time has
1880*c53c97f7SRobert Mustacchi * elapsed since the last time we printed (e.g. 1s)
1881*c53c97f7SRobert Mustacchi *
1882*c53c97f7SRobert Mustacchi * We always let the siginfo handler take priority here.
1883*c53c97f7SRobert Mustacchi */
1884*c53c97f7SRobert Mustacchi if (main_loop) {
1885*c53c97f7SRobert Mustacchi if (nstats == 0 && status_arg != DD_STATUS_PROGRESS) {
1886*c53c97f7SRobert Mustacchi return;
1887*c53c97f7SRobert Mustacchi }
1888*c53c97f7SRobert Mustacchi
1889*c53c97f7SRobert Mustacchi if (nstats == 0 && status_arg == DD_STATUS_PROGRESS) {
1890*c53c97f7SRobert Mustacchi uint64_t num_secs = delta / NANOSEC;
1891*c53c97f7SRobert Mustacchi
1892*c53c97f7SRobert Mustacchi if (num_secs <= prog_secs) {
1893*c53c97f7SRobert Mustacchi return;
1894*c53c97f7SRobert Mustacchi }
1895*c53c97f7SRobert Mustacchi
1896*c53c97f7SRobert Mustacchi prog_secs = num_secs;
1897*c53c97f7SRobert Mustacchi is_progress = B_TRUE;
1898*c53c97f7SRobert Mustacchi if (stderr_tty) {
1899*c53c97f7SRobert Mustacchi head = "\r";
1900*c53c97f7SRobert Mustacchi tail = "";
1901*c53c97f7SRobert Mustacchi }
1902*c53c97f7SRobert Mustacchi }
1903*c53c97f7SRobert Mustacchi
1904*c53c97f7SRobert Mustacchi if (nstats == 1) {
1905*c53c97f7SRobert Mustacchi nstats = 0;
1906*c53c97f7SRobert Mustacchi }
1907*c53c97f7SRobert Mustacchi }
1908*c53c97f7SRobert Mustacchi
1909*c53c97f7SRobert Mustacchi /*
1910*c53c97f7SRobert Mustacchi * When we output to a tty with status=progress we do so by only
1911*c53c97f7SRobert Mustacchi * emitting carriage returns and overwriting. This means that when we
1912*c53c97f7SRobert Mustacchi * come in here for any other reason we need to emit a new line so we
1913*c53c97f7SRobert Mustacchi * don't end up clobbering anything.
1914*c53c97f7SRobert Mustacchi *
1915*c53c97f7SRobert Mustacchi * The progress_printed boolean is basically here to make sure we have
1916*c53c97f7SRobert Mustacchi * actually printed out a status line that would cause us to need a new
1917*c53c97f7SRobert Mustacchi * line. If we finished say after a SIGINFO output but before the next
1918*c53c97f7SRobert Mustacchi * progress output this would result in an extraneous newline.
1919*c53c97f7SRobert Mustacchi */
1920*c53c97f7SRobert Mustacchi if (!is_progress && status_arg == DD_STATUS_PROGRESS && stderr_tty &&
1921*c53c97f7SRobert Mustacchi progress_printed) {
1922*c53c97f7SRobert Mustacchi (void) fputc('\n', stderr);
1923*c53c97f7SRobert Mustacchi }
1924*c53c97f7SRobert Mustacchi
1925*c53c97f7SRobert Mustacchi if (!is_progress) {
1926*c53c97f7SRobert Mustacchi (void) fprintf(stderr, gettext("%llu+%llu records in\n"),
1927*c53c97f7SRobert Mustacchi nifr, nipr);
1928*c53c97f7SRobert Mustacchi (void) fprintf(stderr, gettext("%llu+%llu records out\n"),
1929*c53c97f7SRobert Mustacchi nofr, nopr);
19307c478bd9Sstevel@tonic-gate if (ntrunc) {
19317c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
19327c478bd9Sstevel@tonic-gate gettext("%llu truncated record(s)\n"), ntrunc);
19337c478bd9Sstevel@tonic-gate }
1934*c53c97f7SRobert Mustacchi }
193519d32b9aSRobert Mustacchi
193619d32b9aSRobert Mustacchi /*
193719d32b9aSRobert Mustacchi * If we got here before we started copying somehow, don't bother
193819d32b9aSRobert Mustacchi * printing the rest.
193919d32b9aSRobert Mustacchi */
1940*c53c97f7SRobert Mustacchi if (startt == 0 || status_arg == DD_STATUS_NOXFER)
194119d32b9aSRobert Mustacchi return;
194219d32b9aSRobert Mustacchi
1943*c53c97f7SRobert Mustacchi nicenum_scale((uint64_t)obytes / secs, 1, bps, sizeof (bps),
1944*c53c97f7SRobert Mustacchi NN_UNIT_SPACE);
1945*c53c97f7SRobert Mustacchi nicenum_scale(obytes, 1, hobytes, sizeof (hobytes), NN_UNIT_SPACE);
194619d32b9aSRobert Mustacchi (void) fprintf(stderr,
1947*c53c97f7SRobert Mustacchi gettext("%s%llu bytes (%siB) transferred in %.6f secs "
1948*c53c97f7SRobert Mustacchi "(%siB/sec)%s"), head, obytes, hobytes, secs, bps, tail);
1949*c53c97f7SRobert Mustacchi
1950*c53c97f7SRobert Mustacchi progress_printed = is_progress;
19517c478bd9Sstevel@tonic-gate }
1952