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