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