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