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