17bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/* $NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc Exp $ */ 27bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 37bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/*- 47bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Copyright (c) 1991, 1993, 1994 57bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * The Regents of the University of California. All rights reserved. 67bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * 77bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * This code is derived from software contributed to Berkeley by 87bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Keith Muller of the University of California, San Diego and Lance 97bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Visser of Convex Computer Corporation. 107bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * 117bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Redistribution and use in source and binary forms, with or without 127bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * modification, are permitted provided that the following conditions 137bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * are met: 147bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * 1. Redistributions of source code must retain the above copyright 157bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * notice, this list of conditions and the following disclaimer. 167bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * 2. Redistributions in binary form must reproduce the above copyright 177bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * notice, this list of conditions and the following disclaimer in the 187bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * documentation and/or other materials provided with the distribution. 197bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * 3. Neither the name of the University nor the names of its contributors 207bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * may be used to endorse or promote products derived from this software 217bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * without specific prior written permission. 227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * 237bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 247bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 257bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 267bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 277bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 287bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 297bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 307bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 317bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 327bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 337bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * SUCH DAMAGE. 347bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <sys/cdefs.h> 377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#ifndef lint 387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#if 0 397bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesstatic char sccsid[] = "@(#)conv.c 8.3 (Berkeley) 4/2/94"; 407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#else 417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes__RCSID("$NetBSD: conv.c,v 1.17 2003/08/07 09:05:10 agc Exp $"); 427bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif 437bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif /* not lint */ 447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 457bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <sys/param.h> 467bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <sys/time.h> 477bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 487bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <err.h> 497bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <string.h> 507bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include <stdlib.h> 517bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 527bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include "dd.h" 537bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#include "extern.h" 547bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/* 567bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * def -- 577bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Copy input to output. Input is buffered until reaches obs, and then 587bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * output until less than obs remains. Only a single buffer is used. 597bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Worst case buffer calculation is (ibs + obs - 1). 607bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 617bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 627bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesdef(void) 637bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{ 647bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes uint64_t cnt; 657bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes u_char *inp; 667bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes const u_char *t; 677bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 687bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if ((t = ctab) != NULL) 697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp) 707bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes *inp = t[*inp]; 717bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 727bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* Make the output buffer look right. */ 737bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbp = in.dbp; 747bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbcnt = in.dbcnt; 757bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 767bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (in.dbcnt >= out.dbsz) { 777bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* If the output buffer is full, write it. */ 787bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes dd_out(0); 797bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 807bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* 817bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Ddout copies the leftover output to the beginning of 827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * the buffer and resets the output buffer. Reset the 837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * input buffer to match it. 847bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 857bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbp = out.dbp; 867bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbcnt = out.dbcnt; 877bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 887bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes} 897bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 907bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 917bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesdef_close(void) 927bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{ 937bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 947bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* Just update the count, everything is already in the buffer. */ 957bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (in.dbcnt) 967bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbcnt = in.dbcnt; 977bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes} 987bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 997bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#ifdef NO_CONV 1007bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/* Build a smaller version (i.e. for a miniroot) */ 1017bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/* These can not be called, but just in case... */ 1027bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesstatic const char no_block[] = "unblock and -DNO_CONV?"; 1037bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid block(void) { errx(EXIT_FAILURE, "%s", no_block + 2); } 1047bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid block_close(void) { errx(EXIT_FAILURE, "%s", no_block + 2); } 1057bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid unblock(void) { errx(EXIT_FAILURE, "%s", no_block); } 1067bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid unblock_close(void) { errx(EXIT_FAILURE, "%s", no_block); } 1077bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#else /* NO_CONV */ 1087bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1097bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/* 1107bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Copy variable length newline terminated records with a max size cbsz 1117bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * bytes to output. Records less than cbs are padded with spaces. 1127bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * 1137bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * max in buffer: MAX(ibs, cbsz) 1147bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * max out buffer: obs + cbsz 1157bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 1167bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 1177bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesblock(void) 1187bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{ 1197bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes static int intrunc; 1207bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes int ch = 0; /* pacify gcc */ 1217bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes uint64_t cnt, maxlen; 1227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes u_char *inp, *outp; 1237bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes const u_char *t; 1247bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1257bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* 1267bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Record truncation can cross block boundaries. If currently in a 1277bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * truncation state, keep tossing characters until reach a newline. 1287bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Start at the beginning of the buffer, as the input buffer is always 1297bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * left empty. 1307bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 1317bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (intrunc) { 1327bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (inp = in.db, cnt = in.dbrcnt; 1337bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes cnt && *inp++ != '\n'; --cnt); 1347bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (!cnt) { 1357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbcnt = 0; 1367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbp = in.db; 1377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes return; 1387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1397bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes intrunc = 0; 1407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* Adjust the input buffer numbers. */ 1417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbcnt = cnt - 1; 1427bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbp = inp + cnt - 1; 1437bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1457bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* 1467bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Copy records (max cbsz size chunks) into the output buffer. The 1477bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * translation is done as we copy into the output buffer. 1487bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 1497bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) { 1507bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes maxlen = MIN(cbsz, in.dbcnt); 1517bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if ((t = ctab) != NULL) 1527bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (cnt = 0; 1537bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes cnt < maxlen && (ch = *inp++) != '\n'; ++cnt) 1547bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes *outp++ = t[ch]; 1557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes else 1567bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (cnt = 0; 1577bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes cnt < maxlen && (ch = *inp++) != '\n'; ++cnt) 1587bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes *outp++ = ch; 1597bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* 1607bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Check for short record without a newline. Reassemble the 1617bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * input block. 1627bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 1637bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (ch != '\n' && in.dbcnt < cbsz) { 1647bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt); 1657bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes break; 1667bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1677bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1687bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* Adjust the input buffer numbers. */ 1697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbcnt -= cnt; 1707bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (ch == '\n') 1717bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes --in.dbcnt; 1727bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1737bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* Pad short records with spaces. */ 1747bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (cnt < cbsz) 1757bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt); 1767bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes else { 1777bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* 1787bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * If the next character wouldn't have ended the 1797bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * block, it's a truncation. 1807bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 1817bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (!in.dbcnt || *inp != '\n') 1827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes ++st.trunc; 1837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1847bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* Toss characters to a newline. */ 1857bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt); 1867bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (!in.dbcnt) 1877bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes intrunc = 1; 1887bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes else 1897bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes --in.dbcnt; 1907bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1917bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 1927bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* Adjust output buffer numbers. */ 1937bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbp += cbsz; 1947bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if ((out.dbcnt += cbsz) >= out.dbsz) 1957bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes dd_out(0); 1967bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes outp = out.dbp; 1977bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 1987bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbp = in.db + in.dbcnt; 1997bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes} 2007bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 2017bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 2027bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesblock_close(void) 2037bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{ 2047bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 2057bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* 2067bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Copy any remaining data into the output buffer and pad to a record. 2077bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Don't worry about truncation or translation, the input buffer is 2087bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * always empty when truncating, and no characters have been added for 2097bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * translation. The bottom line is that anything left in the input 2107bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * buffer is a truncated record. Anything left in the output buffer 2117bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * just wasn't big enough. 2127bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 2137bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (in.dbcnt) { 2147bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes ++st.trunc; 2157bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt); 2167bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)memset(out.dbp + in.dbcnt, 2177bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes ctab ? ctab[' '] : ' ', cbsz - in.dbcnt); 2187bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbcnt += cbsz; 2197bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 2207bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes} 2217bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 2227bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes/* 2237bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Convert fixed length (cbsz) records to variable length. Deletes any 2247bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * trailing blanks and appends a newline. 2257bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * 2267bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * max in buffer: MAX(ibs, cbsz) + cbsz 2277bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * max out buffer: obs + cbsz 2287bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 2297bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 2307bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesunblock(void) 2317bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{ 2327bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes uint64_t cnt; 2337bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes u_char *inp; 2347bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes const u_char *t; 2357bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 2367bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* Translation and case conversion. */ 2377bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if ((t = ctab) != NULL) 2387bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--) 2397bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes *inp = t[*inp]; 2407bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes /* 2417bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * Copy records (max cbsz size chunks) into the output buffer. The 2427bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * translation has to already be done or we might not recognize the 2437bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes * spaces. 2447bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes */ 2457bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) { 2467bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t); 2477bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (t >= inp) { 2487bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes cnt = t - inp + 1; 2497bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)memmove(out.dbp, inp, cnt); 2507bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbp += cnt; 2517bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbcnt += cnt; 2527bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 2537bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes ++out.dbcnt; 2547bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes *out.dbp++ = '\n'; 2557bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (out.dbcnt >= out.dbsz) 2567bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes dd_out(0); 2577bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 2587bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (in.dbcnt) 2597bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt); 2607bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes in.dbp = in.db + in.dbcnt; 2617bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes} 2627bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 2637bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesvoid 2647bb5660647d0106f96b000c25f5690a45734c38cElliott Hughesunblock_close(void) 2657bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes{ 2667bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes uint64_t cnt; 2677bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes u_char *t; 2687bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 2697bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (in.dbcnt) { 2707bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes warnx("%s: short input record", in.name); 2717bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t); 2727bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes if (t >= in.db) { 2737bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes cnt = t - in.db + 1; 2747bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes (void)memmove(out.dbp, in.db, cnt); 2757bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbp += cnt; 2767bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes out.dbcnt += cnt; 2777bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 2787bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes ++out.dbcnt; 2797bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes *out.dbp++ = '\n'; 2807bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes } 2817bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes} 2827bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes 2837bb5660647d0106f96b000c25f5690a45734c38cElliott Hughes#endif /* NO_CONV */ 284