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