dd.c revision dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0
1dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*	$NetBSD: dd.c,v 1.37 2004/01/17 21:00:16 dbj Exp $	*/
2dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
3dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*-
4dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copyright (c) 1991, 1993, 1994
5dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *	The Regents of the University of California.  All rights reserved.
6dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
7dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * This code is derived from software contributed to Berkeley by
8dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Keith Muller of the University of California, San Diego and Lance
9dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Visser of Convex Computer Corporation.
10dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
11dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Redistribution and use in source and binary forms, with or without
12dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * modification, are permitted provided that the following conditions
13dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * are met:
14dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 1. Redistributions of source code must retain the above copyright
15dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer.
16dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright
17dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    notice, this list of conditions and the following disclaimer in the
18dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    documentation and/or other materials provided with the distribution.
19dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * 3. Neither the name of the University nor the names of its contributors
20dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    may be used to endorse or promote products derived from this software
21dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *    without specific prior written permission.
22dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
23dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * SUCH DAMAGE.
34dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
35dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
36dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/cdefs.h>
37dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef lint
38dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\n\
39dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	The Regents of the University of California.  All rights reserved.\n");
40dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* not lint */
41dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
42dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef lint
43dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#if 0
44dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic char sccsid[] = "@(#)dd.c	8.5 (Berkeley) 4/2/94";
45dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else
46dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project__RCSID("$NetBSD: dd.c,v 1.37 2004/01/17 21:00:16 dbj Exp $");
47dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
48dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif /* not lint */
49dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
50dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/param.h>
51dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/stat.h>
52dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/ioctl.h>
53dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <sys/time.h>
54dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
55dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <ctype.h>
56dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <err.h>
57dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <errno.h>
58dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <fcntl.h>
59dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <signal.h>
60dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdio.h>
61dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <stdlib.h>
62dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <string.h>
63dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include <unistd.h>
64dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
65dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#include "dd.h"
66dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
67dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define NO_CONV
68dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
69dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//#include "extern.h"
70dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid block(void);
71dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid block_close(void);
72dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid dd_out(int);
73dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid def(void);
74dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid def_close(void);
75dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid jcl(char **);
76dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid pos_in(void);
77dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid pos_out(void);
78dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid summary(void);
79dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid summaryx(int);
80dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid terminate(int);
81dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid unblock(void);
82dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid unblock_close(void);
83dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectssize_t bwrite(int, const void *, size_t);
84dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
85dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern IO		in, out;
86dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern STAT		st;
87dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern void		(*cfunc)(void);
88dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern uint64_t		cpy_cnt;
89dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern uint64_t		cbsz;
90dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern u_int		ddflags;
91dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern u_int		files_cnt;
92dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern int		progress;
93dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern const u_char	*ctab;
94dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern const u_char	a2e_32V[], a2e_POSIX[];
95dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern const u_char	e2a_32V[], e2a_POSIX[];
96dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern const u_char	a2ibm_32V[], a2ibm_POSIX[];
97dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectextern u_char		casetab[];
98dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
99dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define MAX(a, b) ((a) > (b) ? (a) : (b))
101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dd_close(void);
103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void dd_in(void);
104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void getfdtype(IO *);
105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int redup_clean_fd(int);
106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void setup(void);
107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectIO		in, out;		/* input/output state */
110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source ProjectSTAT		st;			/* statistics */
111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid		(*cfunc)(void);		/* conversion function */
112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint64_t	cpy_cnt;		/* # of blocks to copy */
113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic off_t	pending = 0;		/* pending seek if sparse */
114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectu_int		ddflags;		/* conversion options */
115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectuint64_t	cbsz;			/* conversion block size */
116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectu_int		files_cnt = 1;		/* # of files to copy */
117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint		progress = 0;		/* display sign of life */
118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectconst u_char	*ctab;			/* conversion table */
119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsigset_t	infoset;		/* a set blocking SIGINFO */
120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectint
122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdd_main(int argc, char *argv[])
123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int ch;
125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while ((ch = getopt(argc, argv, "")) != -1) {
127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		switch (ch) {
128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		default:
129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "usage: dd [operand ...]\n");
130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	argc -= (optind - 1);
135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	argv += (optind - 1);
136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	jcl(argv);
138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	setup();
139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//	(void)signal(SIGINFO, summaryx);
141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)signal(SIGINT, terminate);
142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)sigemptyset(&infoset);
143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//	(void)sigaddset(&infoset, SIGINFO);
144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)atexit(summary);
146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (files_cnt--)
148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		dd_in();
149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	dd_close();
151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	exit(0);
152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* NOTREACHED */
153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsetup(void)
157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (in.name == NULL) {
160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.name = "stdin";
161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.fd = STDIN_FILENO;
162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.fd = open(in.name, O_RDONLY, 0);
164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (in.fd < 0) {
165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "%s: cannot open for read: %s\n",
166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				in.name, strerror(errno));
167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Ensure in.fd is outside the stdio descriptor range */
172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.fd = redup_clean_fd(in.fd);
173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	getfdtype(&in);
176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (files_cnt > 1 && !(in.flags & ISTAPE)) {
178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr,
179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			"files is not supported for non-tape devices\n");
180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		exit(1);
181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (out.name == NULL) {
185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* No way to check for read access here. */
186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.fd = STDOUT_FILENO;
187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.name = "stdout";
188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else {
189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define	OFLAGS \
190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project    (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.fd = open(out.name, O_RDWR | OFLAGS /*, DEFFILEMODE */);
192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * May not have read access, so try again with write only.
194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * Without read we may have a problem if output also does
195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * not support seeks.
196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (out.fd < 0) {
198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out.fd = open(out.name, O_WRONLY | OFLAGS /*, DEFFILEMODE */);
199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out.flags |= NOREAD;
200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (out.fd < 0) {
202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "%s: cannot open for write: %s\n",
203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				out.name, strerror(errno));
204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Ensure out.fd is outside the stdio descriptor range */
209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.fd = redup_clean_fd(out.fd);
210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	getfdtype(&out);
213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Allocate space for the input and output buffers.  If not doing
216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * record oriented I/O, only need a single buffer.
217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL) {
220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.db = in.db;
224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else if ((in.db =
225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL ||
226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL) {
227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		exit(1);
228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	in.dbp = in.db;
231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	out.dbp = out.db;
232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Position the input/output streams. */
234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (in.offset)
235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		pos_in();
236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (out.offset)
237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		pos_out();
238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Truncate the output file; ignore errors because it fails on some
241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * kinds of output files, tapes, for example.
242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)ftruncate(out.fd, (off_t)out.offset * out.dbsz);
245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * If converting case at the same time as another conversion, build a
248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * table that does both at once.  If just converting case, use the
249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * built-in tables.
250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (ddflags & (C_LCASE|C_UCASE)) {
252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef	NO_CONV
253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Should not get here, but just in case... */
254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr, "case conv and -DNO_CONV\n");
255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		exit(1);
256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else	/* NO_CONV */
258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		u_int cnt;
259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ddflags & C_ASCII || ddflags & C_EBCDIC) {
261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ddflags & C_LCASE) {
262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				for (cnt = 0; cnt < 0377; ++cnt)
263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					casetab[cnt] = tolower(ctab[cnt]);
264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else {
265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				for (cnt = 0; cnt < 0377; ++cnt)
266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					casetab[cnt] = toupper(ctab[cnt]);
267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ddflags & C_LCASE) {
270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				for (cnt = 0; cnt < 0377; ++cnt)
271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					casetab[cnt] = tolower(cnt);
272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else {
273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				for (cnt = 0; cnt < 0377; ++cnt)
274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					casetab[cnt] = toupper(cnt);
275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ctab = casetab;
279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif	/* NO_CONV */
280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)gettimeofday(&st.start, NULL);	/* Statistics timestamp. */
283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectgetfdtype(IO *io)
287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//	struct mtget mt;
289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct stat sb;
290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (fstat(io->fd, &sb)) {
292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr, "%s: cannot fstat: %s\n",
293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			io->name, strerror(errno));
294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		exit(1);
295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (S_ISCHR(sb.st_mode))
298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		io->flags |= /*ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE; */ ISCHR;
299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	else if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		io->flags |= ISPIPE;		/* XXX fixed in 4.4BSD */
301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Move the parameter file descriptor to a descriptor that is outside the
305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * stdio descriptor range, if necessary.  This is required to avoid
306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * accidentally outputting completion or error messages into the
307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * output file that were intended for the tty.
308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectredup_clean_fd(int fd)
311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int newfd;
313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    fd != STDERR_FILENO)
316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* File descriptor is ok, return immediately. */
317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return fd;
318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * 3 is the first descriptor greater than STD*_FILENO.  Any
321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * free descriptor valued 3 or above is acceptable...
322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	newfd = fcntl(fd, F_DUPFD, 3);
324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (newfd < 0) {
325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr, "dupfd IO: %s\n", strerror(errno));
326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		exit(1);
327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	close(fd);
331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return newfd;
333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdd_in(void)
337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int flags;
339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int64_t n;
340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (flags = ddflags;;) {
342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return;
344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * Clear the buffer first if doing "sync" on input.
347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * If doing block operations use spaces.  This will
348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * affect not only the C_NOERROR case, but also the
349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * last partial input block which should be padded
350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * with zero and not garbage.
351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (flags & C_SYNC) {
353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (flags & (C_BLOCK|C_UNBLOCK))
354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				(void)memset(in.dbp, ' ', in.dbsz);
355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else
356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				(void)memset(in.dbp, 0, in.dbsz);
357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
359dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		n = read(in.fd, in.dbp, in.dbsz);
360dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (n == 0) {
361dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			in.dbrcnt = 0;
362dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return;
363dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
364dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
365dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Read error. */
366dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (n < 0) {
367dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
368dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
369dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * If noerror not specified, die.  POSIX requires that
370dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * the warning message be followed by an I/O display.
371dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 */
372dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "%s: read error: %s\n",
373dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				in.name, strerror(errno));
374dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!(flags & C_NOERROR)) {
375dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				exit(1);
376dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				/* NOTREACHED */
377dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
378dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			summary();
379dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
380dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
381dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * If it's not a tape drive or a pipe, seek past the
382dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * error.  If your OS doesn't do the right thing for
383dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * raw disks this section should be modified to re-read
384dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * in sector size chunks.
385dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 */
386dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!(in.flags & (ISPIPE|ISTAPE)) &&
387dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
388dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				fprintf(stderr, "%s: seek error: %s\n",
389dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					in.name, strerror(errno));
390dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
391dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* If sync not specified, omit block and continue. */
392dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!(ddflags & C_SYNC))
393dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
394dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
395dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* Read errors count as full blocks. */
396dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			in.dbcnt += in.dbrcnt = in.dbsz;
397dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++st.in_full;
398dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
399dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Handle full input blocks. */
400dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else if (n == in.dbsz) {
401dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			in.dbcnt += in.dbrcnt = n;
402dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++st.in_full;
403dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
404dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Handle partial input blocks. */
405dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
406dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* If sync, use the entire block. */
407dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ddflags & C_SYNC)
408dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				in.dbcnt += in.dbrcnt = in.dbsz;
409dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else
410dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				in.dbcnt += in.dbrcnt = n;
411dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++st.in_part;
412dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
413dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
414dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
415dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * POSIX states that if bs is set and no other conversions
416dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * than noerror, notrunc or sync are specified, the block
417dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * is output without buffering as it is read.
418dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
419dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ddflags & C_BS) {
420dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out.dbcnt = in.dbcnt;
421dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dd_out(1);
422dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			in.dbcnt = 0;
423dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
424dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
425dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
426dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*		if (ddflags & C_SWAB) {
427dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((n = in.dbrcnt) & 1) {
428dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				++st.swab;
429dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				--n;
430dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
431dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			swab(in.dbp, in.dbp, n);
432dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
433dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project*/
434dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.dbp += in.dbrcnt;
435dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(*cfunc)();
436dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
437dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
438dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
439dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
440dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Cleanup any remaining I/O and flush output.  If necesssary, output file
441dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * is truncated.
442dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
443dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
444dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdd_close(void)
445dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
446dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
447dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (cfunc == def)
448dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		def_close();
449dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	else if (cfunc == block)
450dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		block_close();
451dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	else if (cfunc == unblock)
452dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		unblock_close();
453dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) {
454dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)memset(out.dbp, 0, out.dbsz - out.dbcnt);
455dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.dbcnt = out.dbsz;
456dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
457dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* If there are pending sparse blocks, make sure
458dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * to write out the final block un-sparse
459dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
460dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((out.dbcnt == 0) && pending) {
461dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		memset(out.db, 0, out.dbsz);
462dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.dbcnt = out.dbsz;
463dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.dbp = out.db + out.dbcnt;
464dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		pending -= out.dbsz;
465dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
466dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (out.dbcnt)
467dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		dd_out(1);
468dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
469dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
470dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Reporting nfs write error may be defered until next
471dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * write(2) or close(2) system call.  So, we need to do an
472dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * extra check.  If an output is stdout, the file structure
473dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * may be shared among with other processes and close(2) just
474dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * decreases the reference count.
475dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
476dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (out.fd == STDOUT_FILENO && fsync(out.fd) == -1 && errno != EINVAL) {
477dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr, "fsync stdout: %s\n", strerror(errno));
478dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		exit(1);
479dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
480dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
481dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (close(out.fd) == -1) {
482dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr, "close: %s\n", strerror(errno));
483dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		exit(1);
484dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
485dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
486dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
487dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
488dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
489dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdd_out(int force)
490dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
491dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	static int warned;
492dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int64_t cnt, n, nw;
493dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	u_char *outp;
494dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
495dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
496dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Write one or more blocks out.  The common case is writing a full
497dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * output block in a single write; increment the full block stats.
498dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Otherwise, we're into partial block writes.  If a partial write,
499dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * and it's a character device, just warn.  If a tape device, quit.
500dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 *
501dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * The partial writes represent two cases.  1: Where the input block
502dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * was less than expected so the output block was less than expected.
503dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * 2: Where the input block was the right size but we were forced to
504dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * write the block in multiple chunks.  The original versions of dd(1)
505dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * never wrote a block in more than a single write, so the latter case
506dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * never happened.
507dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 *
508dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * One special case is if we're forced to do the write -- in that case
509dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * we play games with the buffer size, and it's usually a partial write.
510dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
511dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	outp = out.db;
512dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
513dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (cnt = n;; cnt -= nw) {
514dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
515dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!force && ddflags & C_SPARSE) {
516dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				int sparse, i;
517dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				sparse = 1;	/* Is buffer sparse? */
518dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				for (i = 0; i < cnt; i++)
519dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					if (outp[i] != 0) {
520dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						sparse = 0;
521dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						break;
522dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					}
523dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (sparse) {
524dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					pending += cnt;
525dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					outp += cnt;
526dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					nw = 0;
527dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					break;
528dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
529dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
530dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (pending != 0) {
531dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (lseek(out.fd, pending, SEEK_CUR) ==
532dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				    -1) {
533dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					fprintf(stderr,
534dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						"%s: seek error creating "
535dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						"sparse file: %s\n",
536dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						out.name, strerror(errno));
537dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					exit(1);
538dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
539dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
540dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			nw = bwrite(out.fd, outp, cnt);
541dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (nw <= 0) {
542dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (nw == 0) {
543dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					fprintf(stderr, "%s: end of device\n",
544dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						out.name);
545dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					exit(1);
546dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					/* NOTREACHED */
547dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
548dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (errno != EINTR) {
549dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					fprintf(stderr, "%s: write error: %s\n",
550dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project						out.name, strerror(errno));
551dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					/* NOTREACHED */
552dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					exit(1);
553dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
554dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				nw = 0;
555dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
556dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (pending) {
557dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				st.bytes += pending;
558dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				st.sparse += pending/out.dbsz;
559dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				st.out_full += pending/out.dbsz;
560dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				pending = 0;
561dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
562dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			outp += nw;
563dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			st.bytes += nw;
564dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (nw == n) {
565dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (n != out.dbsz)
566dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					++st.out_part;
567dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				else
568dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					++st.out_full;
569dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				break;
570dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
571dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			++st.out_part;
572dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (nw == cnt)
573dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				break;
574dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (out.flags & ISCHR && !warned) {
575dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				warned = 1;
576dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				fprintf(stderr, "%s: short write on character "
577dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					"device\n", out.name);
578dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
579dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (out.flags & ISTAPE) {
580dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				fprintf(stderr,
581dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					"%s: short write on tape device",
582dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					out.name);
583dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				exit(1);
584dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				/* NOTREACHED */
585dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
586dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
587dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((out.dbcnt -= n) < out.dbsz)
588dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
589dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
590dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
591dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Reassemble the output block. */
592dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (out.dbcnt)
593dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt);
594dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	out.dbp = out.db + out.dbcnt;
595dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
596dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (progress)
597dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)write(STDERR_FILENO, ".", 1);
598dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
599dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
600dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
601dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * A protected against SIGINFO write
602dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
603dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectssize_t
604dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectbwrite(int fd, const void *buf, size_t len)
605dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
606dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	sigset_t oset;
607dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	ssize_t rv;
608dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int oerrno;
609dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
610dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)sigprocmask(SIG_BLOCK, &infoset, &oset);
611dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	rv = write(fd, buf, len);
612dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	oerrno = errno;
613dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
614dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	errno = oerrno;
615dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (rv);
616dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
617dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
618dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
619dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Position input/output data streams before starting the copy.  Device type
620dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * dependent.  Seekable devices use lseek, and the rest position by reading.
621dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Seeking past the end of file can cause null blocks to be written to the
622dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * output.
623dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
624dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
625dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpos_in(void)
626dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
627dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int bcnt, cnt, nr, warned;
628dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
629dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* If not a pipe or tape device, try to seek on it. */
630dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!(in.flags & (ISPIPE|ISTAPE))) {
631dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (lseek(in.fd,
632dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    (off_t)in.offset * (off_t)in.dbsz, SEEK_CUR) == -1) {
633dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "%s: seek error: %s",
634dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				in.name, strerror(errno));
635dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
636dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
637dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
638dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return;
639dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
640dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
641dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
642dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
643dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Read the data.  If a pipe, read until satisfy the number of bytes
644dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * being skipped.  No differentiation for reading complete and partial
645dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * blocks for other devices.
646dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
647dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
648dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((nr = read(in.fd, in.db, bcnt)) > 0) {
649dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (in.flags & ISPIPE) {
650dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				if (!(bcnt -= nr)) {
651dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					bcnt = in.dbsz;
652dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					--cnt;
653dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				}
654dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else
655dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				--cnt;
656dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
657dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
658dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
659dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (nr == 0) {
660dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (files_cnt > 1) {
661dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				--files_cnt;
662dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				continue;
663dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
664dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "skip reached end of input\n");
665dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
666dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
667dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
668dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
669dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
670dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * Input error -- either EOF with no more files, or I/O error.
671dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * If noerror not set die.  POSIX requires that the warning
672dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * message be followed by an I/O display.
673dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
674dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ddflags & C_NOERROR) {
675dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!warned) {
676dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
677dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				fprintf(stderr, "%s: error occurred\n",
678dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					in.name);
679dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				warned = 1;
680dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				summary();
681dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
682dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
683dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
684dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		fprintf(stderr, "%s: read error: %s", in.name, strerror(errno));
685dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		exit(1);
686dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* NOTREACHED */
687dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
688dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
689dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
690dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
691dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectpos_out(void)
692dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
693dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project//	struct mtop t_op;
694dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int cnt, n;
695dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
696dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
697dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * If not a tape, try seeking on the file.  Seeking on a pipe is
698dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * going to fail, but don't protect the user -- they shouldn't
699dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * have specified the seek operand.
700dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
701dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!(out.flags & ISTAPE)) {
702dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (lseek(out.fd,
703dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    (off_t)out.offset * (off_t)out.dbsz, SEEK_SET) == -1) {
704dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "%s: seek error: %s\n",
705dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				out.name, strerror(errno));
706dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
707dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
708dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
709dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return;
710dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
711dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
712dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* If no read access, try using mtio. */
713dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (out.flags & NOREAD) {
714dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*		t_op.mt_op = MTFSR;
715dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		t_op.mt_count = out.offset;
716dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
717dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)*/
718dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "%s: cannot read", out.name);
719dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
720dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
721dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		return;
722dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
723dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
724dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Read it. */
725dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (cnt = 0; cnt < out.offset; ++cnt) {
726dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((n = read(out.fd, out.db, out.dbsz)) > 0)
727dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			continue;
728dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
729dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (n < 0) {
730dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "%s: cannot position by reading: %s\n",
731dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				out.name, strerror(errno));
732dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
733dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
734dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
735dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
736dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
737dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * If reach EOF, fill with NUL characters; first, back up over
738dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * the EOF mark.  Note, cnt has not yet been incremented, so
739dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * the EOF read does not count as a seek'd block.
740dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
741dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*		t_op.mt_op = MTBSR;
742dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		t_op.mt_count = 1;
743dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ioctl(out.fd, MTIOCTOP, &t_op) == -1) */ {
744dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "%s: cannot position\n", out.name);
745dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
746dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
747dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
748dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
749dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		while (cnt++ < out.offset)
750dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if ((n = bwrite(out.fd, out.db, out.dbsz)) != out.dbsz) {
751dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				fprintf(stderr, "%s: cannot position "
752dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					"by writing: %s\n",
753dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project					out.name, strerror(errno));
754dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				exit(1);
755dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				/* NOTREACHED */
756dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
757dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		break;
758dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
759dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
760dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
761dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
762dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * def --
763dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copy input to output.  Input is buffered until reaches obs, and then
764dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * output until less than obs remains.  Only a single buffer is used.
765dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Worst case buffer calculation is (ibs + obs - 1).
766dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
767dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
768dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdef(void)
769dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
770dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	uint64_t cnt;
771dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	u_char *inp;
772dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const u_char *t;
773dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
774dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((t = ctab) != NULL)
775dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
776dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*inp = t[*inp];
777dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
778dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Make the output buffer look right. */
779dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	out.dbp = in.dbp;
780dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	out.dbcnt = in.dbcnt;
781dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
782dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (in.dbcnt >= out.dbsz) {
783dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* If the output buffer is full, write it. */
784dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		dd_out(0);
785dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
786dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
787dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * Ddout copies the leftover output to the beginning of
788dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * the buffer and resets the output buffer.  Reset the
789dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * input buffer to match it.
790dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 	 */
791dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.dbp = out.dbp;
792dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.dbcnt = out.dbcnt;
793dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
794dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
795dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
796dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
797dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectdef_close(void)
798dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
799dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
800dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Just update the count, everything is already in the buffer. */
801dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (in.dbcnt)
802dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.dbcnt = in.dbcnt;
803dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
804dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
805dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef	NO_CONV
806dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Build a smaller version (i.e. for a miniroot) */
807dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* These can not be called, but just in case...  */
808dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const char no_block[] = "unblock and -DNO_CONV?\n";
809dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid block(void)		{ fprintf(stderr, "%s", no_block + 2); exit(1); }
810dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid block_close(void)		{ fprintf(stderr, "%s", no_block + 2); exit(1); }
811dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid unblock(void)		{ fprintf(stderr, "%s", no_block); exit(1); }
812dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid unblock_close(void)	{ fprintf(stderr, "%s", no_block); exit(1); }
813dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else	/* NO_CONV */
814dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
815dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
816dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Copy variable length newline terminated records with a max size cbsz
817dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * bytes to output.  Records less than cbs are padded with spaces.
818dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
819dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * max in buffer:  MAX(ibs, cbsz)
820dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * max out buffer: obs + cbsz
821dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
822dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
823dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectblock(void)
824dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
825dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	static int intrunc;
826dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int ch = 0;	/* pacify gcc */
827dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	uint64_t cnt, maxlen;
828dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	u_char *inp, *outp;
829dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const u_char *t;
830dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
831dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
832dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Record truncation can cross block boundaries.  If currently in a
833dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * truncation state, keep tossing characters until reach a newline.
834dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Start at the beginning of the buffer, as the input buffer is always
835dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * left empty.
836dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
837dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (intrunc) {
838dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (inp = in.db, cnt = in.dbrcnt;
839dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    cnt && *inp++ != '\n'; --cnt);
840dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!cnt) {
841dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			in.dbcnt = 0;
842dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			in.dbp = in.db;
843dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			return;
844dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
845dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		intrunc = 0;
846dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Adjust the input buffer numbers. */
847dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.dbcnt = cnt - 1;
848dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.dbp = inp + cnt - 1;
849dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
850dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
851dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
852dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Copy records (max cbsz size chunks) into the output buffer.  The
853dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * translation is done as we copy into the output buffer.
854dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
855dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
856dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		maxlen = MIN(cbsz, in.dbcnt);
857dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((t = ctab) != NULL)
858dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			for (cnt = 0;
859dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
860dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				*outp++ = t[ch];
861dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else
862dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			for (cnt = 0;
863dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
864dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				*outp++ = ch;
865dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
866dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * Check for short record without a newline.  Reassemble the
867dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * input block.
868dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
869dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ch != '\n' && in.dbcnt < cbsz) {
870dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
871dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			break;
872dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
873dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
874dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Adjust the input buffer numbers. */
875dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.dbcnt -= cnt;
876dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ch == '\n')
877dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			--in.dbcnt;
878dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
879dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Pad short records with spaces. */
880dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (cnt < cbsz)
881dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt);
882dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		else {
883dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/*
884dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * If the next character wouldn't have ended the
885dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 * block, it's a truncation.
886dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			 */
887dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!in.dbcnt || *inp != '\n')
888dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				++st.trunc;
889dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
890dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* Toss characters to a newline. */
891dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt);
892dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (!in.dbcnt)
893dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				intrunc = 1;
894dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			else
895dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				--in.dbcnt;
896dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
897dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
898dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Adjust output buffer numbers. */
899dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.dbp += cbsz;
900dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((out.dbcnt += cbsz) >= out.dbsz)
901dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dd_out(0);
902dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		outp = out.dbp;
903dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
904dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	in.dbp = in.db + in.dbcnt;
905dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
906dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
907dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
908dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectblock_close(void)
909dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
910dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
911dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
912dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Copy any remaining data into the output buffer and pad to a record.
913dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Don't worry about truncation or translation, the input buffer is
914dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * always empty when truncating, and no characters have been added for
915dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * translation.  The bottom line is that anything left in the input
916dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * buffer is a truncated record.  Anything left in the output buffer
917dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * just wasn't big enough.
918dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
919dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (in.dbcnt) {
920dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++st.trunc;
921dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
922dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)memset(out.dbp + in.dbcnt,
923dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    ctab ? ctab[' '] : ' ', cbsz - in.dbcnt);
924dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.dbcnt += cbsz;
925dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
926dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
927dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
928dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
929dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * Convert fixed length (cbsz) records to variable length.  Deletes any
930dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * trailing blanks and appends a newline.
931dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project *
932dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * max in buffer:  MAX(ibs, cbsz) + cbsz
933dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * max out buffer: obs + cbsz
934dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
935dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
936dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunblock(void)
937dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
938dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	uint64_t cnt;
939dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	u_char *inp;
940dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const u_char *t;
941dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
942dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Translation and case conversion. */
943dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if ((t = ctab) != NULL)
944dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--)
945dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			*inp = t[*inp];
946dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
947dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Copy records (max cbsz size chunks) into the output buffer.  The
948dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * translation has to already be done or we might not recognize the
949dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * spaces.
950dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
951dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
952dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t);
953dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (t >= inp) {
954dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			cnt = t - inp + 1;
955dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(void)memmove(out.dbp, inp, cnt);
956dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out.dbp += cnt;
957dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out.dbcnt += cnt;
958dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
959dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++out.dbcnt;
960dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*out.dbp++ = '\n';
961dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (out.dbcnt >= out.dbsz)
962dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			dd_out(0);
963dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
964dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (in.dbcnt)
965dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
966dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	in.dbp = in.db + in.dbcnt;
967dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
968dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
969dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
970dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectunblock_close(void)
971dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
972dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	uint64_t cnt;
973dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	u_char *t;
974dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
975dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (in.dbcnt) {
976dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		warnx("%s: short input record", in.name);
977dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t);
978dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (t >= in.db) {
979dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			cnt = t - in.db + 1;
980dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			(void)memmove(out.dbp, in.db, cnt);
981dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out.dbp += cnt;
982dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			out.dbcnt += cnt;
983dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
984dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		++out.dbcnt;
985dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*out.dbp++ = '\n';
986dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
987dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
988dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
989dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif	/* NO_CONV */
990dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
991dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#define	tv2mS(tv) ((tv).tv_sec * 1000LL + ((tv).tv_usec + 500) / 1000)
992dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
993dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
994dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectsummary(void)
995dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
996dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char buf[100];
997dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	int64_t mS;
998dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct timeval tv;
999dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1000dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (progress)
1001dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)write(STDERR_FILENO, "\n", 1);
1002dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1003dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)gettimeofday(&tv, NULL);
1004dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	mS = tv2mS(tv) - tv2mS(st.start);
1005dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (mS == 0)
1006dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		mS = 1;
1007dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Use snprintf(3) so that we don't reenter stdio(3). */
1008dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)snprintf(buf, sizeof(buf),
1009dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    "%llu+%llu records in\n%llu+%llu records out\n",
1010dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    (unsigned long long)st.in_full,  (unsigned long long)st.in_part,
1011dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    (unsigned long long)st.out_full, (unsigned long long)st.out_part);
1012dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)write(STDERR_FILENO, buf, strlen(buf));
1013dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (st.swab) {
1014dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)snprintf(buf, sizeof(buf), "%llu odd length swab %s\n",
1015dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    (unsigned long long)st.swab,
1016dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    (st.swab == 1) ? "block" : "blocks");
1017dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)write(STDERR_FILENO, buf, strlen(buf));
1018dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1019dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (st.trunc) {
1020dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)snprintf(buf, sizeof(buf), "%llu truncated %s\n",
1021dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    (unsigned long long)st.trunc,
1022dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    (st.trunc == 1) ? "block" : "blocks");
1023dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)write(STDERR_FILENO, buf, strlen(buf));
1024dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1025dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (st.sparse) {
1026dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)snprintf(buf, sizeof(buf), "%llu sparse output %s\n",
1027dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    (unsigned long long)st.sparse,
1028dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    (st.sparse == 1) ? "block" : "blocks");
1029dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		(void)write(STDERR_FILENO, buf, strlen(buf));
1030dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1031dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)snprintf(buf, sizeof(buf),
1032dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    "%llu bytes transferred in %lu.%03d secs (%llu bytes/sec)\n",
1033dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    (unsigned long long) st.bytes,
1034dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    (long) (mS / 1000),
1035dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    (int) (mS % 1000),
1036dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    (unsigned long long) (st.bytes * 1000LL / mS));
1037dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	(void)write(STDERR_FILENO, buf, strlen(buf));
1038dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1039dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1040dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
1041dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectterminate(int notused)
1042dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1043dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1044dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	exit(0);
1045dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* NOTREACHED */
1046dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1047dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1048dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int	c_arg(const void *, const void *);
1049dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifndef	NO_CONV
1050dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int	c_conv(const void *, const void *);
1051dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif
1052dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_bs(char *);
1053dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_cbs(char *);
1054dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_conv(char *);
1055dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_count(char *);
1056dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_files(char *);
1057dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_ibs(char *);
1058dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_if(char *);
1059dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_obs(char *);
1060dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_of(char *);
1061dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_seek(char *);
1062dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_skip(char *);
1063dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void	f_progress(char *);
1064dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1065dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const struct arg {
1066dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *name;
1067dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	void (*f)(char *);
1068dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	u_int set, noset;
1069dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} args[] = {
1070dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project     /* the array needs to be sorted by the first column so
1071dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	bsearch() can be used to find commands quickly */
1072dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "bs",		f_bs,		C_BS,	 C_BS|C_IBS|C_OBS|C_OSYNC },
1073dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "cbs",	f_cbs,		C_CBS,	 C_CBS },
1074dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "conv",	f_conv,		0,	 0 },
1075dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "count",	f_count,	C_COUNT, C_COUNT },
1076dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "files",	f_files,	C_FILES, C_FILES },
1077dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "ibs",	f_ibs,		C_IBS,	 C_BS|C_IBS },
1078dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "if",		f_if,		C_IF,	 C_IF },
1079dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "obs",	f_obs,		C_OBS,	 C_BS|C_OBS },
1080dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "of",		f_of,		C_OF,	 C_OF },
1081dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "progress",	f_progress,	0,	 0 },
1082dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "seek",	f_seek,		C_SEEK,	 C_SEEK },
1083dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "skip",	f_skip,		C_SKIP,	 C_SKIP },
1084dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
1085dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1086dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/*
1087dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project * args -- parse JCL syntax of dd.
1088dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project */
1089dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectvoid
1090dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectjcl(char **argv)
1091dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1092dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct arg *ap, tmp;
1093dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	char *oper, *arg;
1094dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1095dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	in.dbsz = out.dbsz = 512;
1096dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1097dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while ((oper = *++argv) != NULL) {
1098dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if ((arg = strchr(oper, '=')) == NULL) {
1099dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "unknown operand %s\n", oper);
1100dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
1101dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
1102dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1103dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		*arg++ = '\0';
1104dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!*arg) {
1105dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "no value specified for %s\n", oper);
1106dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
1107dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
1108dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1109dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tmp.name = oper;
1110dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!(ap = (struct arg *)bsearch(&tmp, args,
1111dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    sizeof(args)/sizeof(struct arg), sizeof(struct arg),
1112dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    c_arg))) {
1113dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "unknown operand %s\n", tmp.name);
1114dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
1115dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
1116dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1117dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ddflags & ap->noset) {
1118dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr,
1119dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    "%s: illegal argument combination or already set\n",
1120dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    tmp.name);
1121dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
1122dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
1123dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1124dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ddflags |= ap->set;
1125dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ap->f(arg);
1126dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1127dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1128dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Final sanity checks. */
1129dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1130dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (ddflags & C_BS) {
1131dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/*
1132dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * Bs is turned off by any conversion -- we assume the user
1133dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * just wanted to set both the input and output block sizes
1134dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 * and didn't want the bs semantics, so we don't warn.
1135dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		 */
1136dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |
1137dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    C_UNBLOCK | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) {
1138dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ddflags &= ~C_BS;
1139dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ddflags |= C_IBS|C_OBS;
1140dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1141dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1142dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		/* Bs supersedes ibs and obs. */
1143dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
1144dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "bs supersedes ibs and obs\n");
1145dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1146dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1147dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/*
1148dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Ascii/ebcdic and cbs implies block/unblock.
1149dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * Block/unblock requires cbs and vice-versa.
1150dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
1151dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (ddflags & (C_BLOCK|C_UNBLOCK)) {
1152dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!(ddflags & C_CBS)) {
1153dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr, "record operations require cbs\n");
1154dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
1155dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
1156dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1157dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		cfunc = ddflags & C_BLOCK ? block : unblock;
1158dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else if (ddflags & C_CBS) {
1159dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ddflags & (C_ASCII|C_EBCDIC)) {
1160dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			if (ddflags & C_ASCII) {
1161dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ddflags |= C_UNBLOCK;
1162dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				cfunc = unblock;
1163dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			} else {
1164dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				ddflags |= C_BLOCK;
1165dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project				cfunc = block;
1166dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			}
1167dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		} else {
1168dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			fprintf(stderr,
1169dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			    "cbs meaningless if not doing record operations\n");
1170dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			exit(1);
1171dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
1172dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1173dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	} else
1174dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		cfunc = def;
1175dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1176dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* Read, write and seek calls take off_t as arguments.
1177dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 *
1178dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * The following check is not done because an off_t is a quad
1179dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 *  for current NetBSD implementations.
1180dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 *
1181dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
1182dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 *	errx(1, "seek offsets cannot be larger than %d", INT_MAX);
1183dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
1184dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1185dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1186dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1187dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectc_arg(const void *a, const void *b)
1188dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1189dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1190dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (strcmp(((const struct arg *)a)->name,
1191dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    ((const struct arg *)b)->name));
1192dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1193dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1194dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic long long strsuftoll(const char* name, const char* arg, int def, unsigned int max)
1195dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1196dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	long long result;
1197dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1198dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (sscanf(arg, "%lld", &result) == 0)
1199dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		result = def;
1200dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return result;
1201dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1202dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1203dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1204dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_bs(char *arg)
1205dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1206dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1207dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX);
1208dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1209dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1210dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1211dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_cbs(char *arg)
1212dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1213dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1214dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX);
1215dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1216dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1217dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1218dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_count(char *arg)
1219dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1220dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1221dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	cpy_cnt = strsuftoll("block count", arg, 0, LLONG_MAX);
1222dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!cpy_cnt)
1223dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		terminate(0);
1224dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1225dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1226dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1227dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_files(char *arg)
1228dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1229dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1230dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX);
1231dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!files_cnt)
1232dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		terminate(0);
1233dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1234dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1235dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1236dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_ibs(char *arg)
1237dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1238dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1239dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!(ddflags & C_BS))
1240dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX);
1241dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1242dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1243dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1244dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_if(char *arg)
1245dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1246dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1247dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	in.name = arg;
1248dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1249dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1250dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1251dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_obs(char *arg)
1252dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1253dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1254dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (!(ddflags & C_BS))
1255dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX);
1256dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1257dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1258dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1259dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_of(char *arg)
1260dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1261dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1262dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	out.name = arg;
1263dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1264dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1265dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1266dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_seek(char *arg)
1267dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1268dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1269dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	out.offset = strsuftoll("seek blocks", arg, 0, LLONG_MAX);
1270dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1271dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1272dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1273dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_skip(char *arg)
1274dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1275dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1276dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	in.offset = strsuftoll("skip blocks", arg, 0, LLONG_MAX);
1277dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1278dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1279dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1280dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_progress(char *arg)
1281dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1282dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1283dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	if (*arg != '0')
1284dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		progress = 1;
1285dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1286dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1287dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#ifdef	NO_CONV
1288dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project/* Build a small version (i.e. for a ramdisk root) */
1289dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1290dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_conv(char *arg)
1291dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1292dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1293dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	fprintf(stderr, "conv option disabled\n");
1294dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	exit(1);
1295dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* NOTREACHED */
1296dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1297dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#else	/* NO_CONV */
1298dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1299dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic const struct conv {
1300dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const char *name;
1301dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	u_int set, noset;
1302dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	const u_char *ctab;
1303dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project} clist[] = {
1304dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "ascii",	C_ASCII,	C_EBCDIC,	e2a_POSIX },
1305dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "block",	C_BLOCK,	C_UNBLOCK,	NULL },
1306dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "ebcdic",	C_EBCDIC,	C_ASCII,	a2e_POSIX },
1307dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "ibm",	C_EBCDIC,	C_ASCII,	a2ibm_POSIX },
1308dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "lcase",	C_LCASE,	C_UCASE,	NULL },
1309dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "noerror",	C_NOERROR,	0,		NULL },
1310dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "notrunc",	C_NOTRUNC,	0,		NULL },
1311dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "oldascii",	C_ASCII,	C_EBCDIC,	e2a_32V },
1312dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "oldebcdic",	C_EBCDIC,	C_ASCII,	a2e_32V },
1313dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "oldibm",	C_EBCDIC,	C_ASCII,	a2ibm_32V },
1314dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "osync",	C_OSYNC,	C_BS,		NULL },
1315dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "sparse",	C_SPARSE,	0,		NULL },
1316dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "swab",	C_SWAB,		0,		NULL },
1317dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "sync",	C_SYNC,		0,		NULL },
1318dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "ucase",	C_UCASE,	C_LCASE,	NULL },
1319dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	{ "unblock",	C_UNBLOCK,	C_BLOCK,	NULL },
1320dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	/* If you add items to this table, be sure to add the
1321dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 * conversions to the C_BS check in the jcl routine above.
1322dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	 */
1323dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project};
1324dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1325dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic void
1326dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectf_conv(char *arg)
1327dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1328dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	struct conv *cp, tmp;
1329dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1330dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	while (arg != NULL) {
1331dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		tmp.name = strsep(&arg, ",");
1332dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (!(cp = (struct conv *)bsearch(&tmp, clist,
1333dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    sizeof(clist)/sizeof(struct conv), sizeof(struct conv),
1334dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		    c_conv))) {
1335dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			errx(EXIT_FAILURE, "unknown conversion %s", tmp.name);
1336dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
1337dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1338dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (ddflags & cp->noset) {
1339dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			errx(EXIT_FAILURE, "%s: illegal conversion combination", tmp.name);
1340dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			/* NOTREACHED */
1341dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		}
1342dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		ddflags |= cp->set;
1343dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project		if (cp->ctab)
1344dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project			ctab = cp->ctab;
1345dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	}
1346dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1347dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1348dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectstatic int
1349dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Projectc_conv(const void *a, const void *b)
1350dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project{
1351dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1352dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	return (strcmp(((const struct conv *)a)->name,
1353dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project	    ((const struct conv *)b)->name));
1354dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project}
1355dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1356dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project#endif	/* NO_CONV */
1357dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1358dd7bc3319deb2b77c5d07a51b7d6cd7e11b5beb0The Android Open Source Project
1359