/*	$NetBSD: dd.c,v 1.37 2004/01/17 21:00:16 dbj Exp $	*/

/*-
 * Copyright (c) 1991, 1993, 1994
 *	The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * Keith Muller of the University of California, San Diego and Lance
 * Visser of Convex Computer Corporation.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/cdefs.h>
#ifndef lint
__COPYRIGHT("@(#) Copyright (c) 1991, 1993, 1994\n\
	The Regents of the University of California.  All rights reserved.\n");
#endif /* not lint */

#ifndef lint
#if 0
static char sccsid[] = "@(#)dd.c	8.5 (Berkeley) 4/2/94";
#else
__RCSID("$NetBSD: dd.c,v 1.37 2004/01/17 21:00:16 dbj Exp $");
#endif
#endif /* not lint */

#include <sys/param.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <sys/time.h>

#include <ctype.h>
#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

#include "dd.h"

//#define NO_CONV

//#include "extern.h"
void block(void);
void block_close(void);
void dd_out(int);
void def(void);
void def_close(void);
void jcl(char **);
void pos_in(void);
void pos_out(void);
void summary(void);
void summaryx(int);
void terminate(int);
void unblock(void);
void unblock_close(void);
ssize_t bwrite(int, const void *, size_t);

extern IO		in, out;
extern STAT		st;
extern void		(*cfunc)(void);
extern uint64_t		cpy_cnt;
extern uint64_t		cbsz;
extern u_int		ddflags;
extern u_int		files_cnt;
extern int		progress;
extern const u_char	*ctab;

#define DEFFILEMODE (S_IRUSR | S_IWUSR)

static void dd_close(void);
static void dd_in(void);
static void getfdtype(IO *);
static int redup_clean_fd(int);
static void setup(void);


IO		in, out;		/* input/output state */
STAT		st;			/* statistics */
void		(*cfunc)(void);		/* conversion function */
uint64_t	cpy_cnt;		/* # of blocks to copy */
static off_t	pending = 0;		/* pending seek if sparse */
u_int		ddflags;		/* conversion options */
uint64_t	cbsz;			/* conversion block size */
u_int		files_cnt = 1;		/* # of files to copy */
int		progress = 0;		/* display sign of life */
const u_char	*ctab;			/* conversion table */
sigset_t	infoset;		/* a set blocking SIGINFO */

int
dd_main(int argc, char *argv[])
{
	int ch;

	while ((ch = getopt(argc, argv, "")) != -1) {
		switch (ch) {
		default:
			fprintf(stderr, "usage: dd [operand ...]\n");
			exit(1);
			/* NOTREACHED */
		}
	}
	argc -= (optind - 1);
	argv += (optind - 1);

	jcl(argv);
	setup();

//	(void)signal(SIGINFO, summaryx);
	(void)signal(SIGINT, terminate);
	(void)sigemptyset(&infoset);
//	(void)sigaddset(&infoset, SIGINFO);

	(void)atexit(summary);

	while (files_cnt--)
		dd_in();

	dd_close();
	exit(0);
	/* NOTREACHED */
}

static void
setup(void)
{

	if (in.name == NULL) {
		in.name = "stdin";
		in.fd = STDIN_FILENO;
	} else {
		in.fd = open(in.name, O_RDONLY, 0);
		if (in.fd < 0) {
			fprintf(stderr, "%s: cannot open for read: %s\n",
				in.name, strerror(errno));
			exit(1);
			/* NOTREACHED */
		}

		/* Ensure in.fd is outside the stdio descriptor range */
		in.fd = redup_clean_fd(in.fd);
	}

	getfdtype(&in);

	if (files_cnt > 1 && !(in.flags & ISTAPE)) {
		fprintf(stderr,
			"files is not supported for non-tape devices\n");
		exit(1);
		/* NOTREACHED */
	}

	if (out.name == NULL) {
		/* No way to check for read access here. */
		out.fd = STDOUT_FILENO;
		out.name = "stdout";
	} else {
#define	OFLAGS \
    (O_CREAT | (ddflags & (C_SEEK | C_NOTRUNC) ? 0 : O_TRUNC))
		out.fd = open(out.name, O_RDWR | OFLAGS, DEFFILEMODE);
		/*
		 * May not have read access, so try again with write only.
		 * Without read we may have a problem if output also does
		 * not support seeks.
		 */
		if (out.fd < 0) {
			out.fd = open(out.name, O_WRONLY | OFLAGS, DEFFILEMODE);
			out.flags |= NOREAD;
		}
		if (out.fd < 0) {
			fprintf(stderr, "%s: cannot open for write: %s\n",
				out.name, strerror(errno));
			exit(1);
			/* NOTREACHED */
		}

		/* Ensure out.fd is outside the stdio descriptor range */
		out.fd = redup_clean_fd(out.fd);
	}

	getfdtype(&out);

	/*
	 * Allocate space for the input and output buffers.  If not doing
	 * record oriented I/O, only need a single buffer.
	 */
	if (!(ddflags & (C_BLOCK|C_UNBLOCK))) {
		if ((in.db = malloc(out.dbsz + in.dbsz - 1)) == NULL) {
			exit(1);
			/* NOTREACHED */
		}
		out.db = in.db;
	} else if ((in.db =
	    malloc((u_int)(MAX(in.dbsz, cbsz) + cbsz))) == NULL ||
	    (out.db = malloc((u_int)(out.dbsz + cbsz))) == NULL) {
		exit(1);
		/* NOTREACHED */
	}
	in.dbp = in.db;
	out.dbp = out.db;

	/* Position the input/output streams. */
	if (in.offset)
		pos_in();
	if (out.offset)
		pos_out();

	/*
	 * Truncate the output file; ignore errors because it fails on some
	 * kinds of output files, tapes, for example.
	 */
	if ((ddflags & (C_OF | C_SEEK | C_NOTRUNC)) == (C_OF | C_SEEK))
		(void)ftruncate(out.fd, (off_t)out.offset * out.dbsz);

	(void)gettimeofday(&st.start, NULL);	/* Statistics timestamp. */
}

static void
getfdtype(IO *io)
{
//	struct mtget mt;
	struct stat sb;

	if (fstat(io->fd, &sb)) {
		fprintf(stderr, "%s: cannot fstat: %s\n",
			io->name, strerror(errno));
		exit(1);
		/* NOTREACHED */
	}
	if (S_ISCHR(sb.st_mode))
		io->flags |= /*ioctl(io->fd, MTIOCGET, &mt) ? ISCHR : ISTAPE; */ ISCHR;
	else if (lseek(io->fd, (off_t)0, SEEK_CUR) == -1 && errno == ESPIPE)
		io->flags |= ISPIPE;		/* XXX fixed in 4.4BSD */
}

/*
 * Move the parameter file descriptor to a descriptor that is outside the
 * stdio descriptor range, if necessary.  This is required to avoid
 * accidentally outputting completion or error messages into the
 * output file that were intended for the tty.
 */
static int
redup_clean_fd(int fd)
{
	int newfd;

	if (fd != STDIN_FILENO && fd != STDOUT_FILENO &&
	    fd != STDERR_FILENO)
		/* File descriptor is ok, return immediately. */
		return fd;

	/*
	 * 3 is the first descriptor greater than STD*_FILENO.  Any
	 * free descriptor valued 3 or above is acceptable...
	 */
	newfd = fcntl(fd, F_DUPFD, 3);
	if (newfd < 0) {
		fprintf(stderr, "dupfd IO: %s\n", strerror(errno));
		exit(1);
		/* NOTREACHED */
	}

	close(fd);

	return newfd;
}

static void
dd_in(void)
{
	int flags;
	int64_t n;

	for (flags = ddflags;;) {
		if (cpy_cnt && (st.in_full + st.in_part) >= cpy_cnt)
			return;

		/*
		 * Clear the buffer first if doing "sync" on input.
		 * If doing block operations use spaces.  This will
		 * affect not only the C_NOERROR case, but also the
		 * last partial input block which should be padded
		 * with zero and not garbage.
		 */
		if (flags & C_SYNC) {
			if (flags & (C_BLOCK|C_UNBLOCK))
				(void)memset(in.dbp, ' ', in.dbsz);
			else
				(void)memset(in.dbp, 0, in.dbsz);
		}

		n = read(in.fd, in.dbp, in.dbsz);
		if (n == 0) {
			in.dbrcnt = 0;
			return;
		}

		/* Read error. */
		if (n < 0) {

			/*
			 * If noerror not specified, die.  POSIX requires that
			 * the warning message be followed by an I/O display.
			 */
			fprintf(stderr, "%s: read error: %s\n",
				in.name, strerror(errno));
			if (!(flags & C_NOERROR)) {
				exit(1);
				/* NOTREACHED */
			}
			summary();

			/*
			 * If it's not a tape drive or a pipe, seek past the
			 * error.  If your OS doesn't do the right thing for
			 * raw disks this section should be modified to re-read
			 * in sector size chunks.
			 */
			if (!(in.flags & (ISPIPE|ISTAPE)) &&
			    lseek(in.fd, (off_t)in.dbsz, SEEK_CUR))
				fprintf(stderr, "%s: seek error: %s\n",
					in.name, strerror(errno));

			/* If sync not specified, omit block and continue. */
			if (!(ddflags & C_SYNC))
				continue;

			/* Read errors count as full blocks. */
			in.dbcnt += in.dbrcnt = in.dbsz;
			++st.in_full;

		/* Handle full input blocks. */
		} else if (n == (int64_t)in.dbsz) {
			in.dbcnt += in.dbrcnt = n;
			++st.in_full;

		/* Handle partial input blocks. */
		} else {
			/* If sync, use the entire block. */
			if (ddflags & C_SYNC)
				in.dbcnt += in.dbrcnt = in.dbsz;
			else
				in.dbcnt += in.dbrcnt = n;
			++st.in_part;
		}

		/*
		 * POSIX states that if bs is set and no other conversions
		 * than noerror, notrunc or sync are specified, the block
		 * is output without buffering as it is read.
		 */
		if (ddflags & C_BS) {
			out.dbcnt = in.dbcnt;
			dd_out(1);
			in.dbcnt = 0;
			continue;
		}

/*		if (ddflags & C_SWAB) {
			if ((n = in.dbrcnt) & 1) {
				++st.swab;
				--n;
			}
			swab(in.dbp, in.dbp, n);
		}
*/
		in.dbp += in.dbrcnt;
		(*cfunc)();
	}
}

/*
 * Cleanup any remaining I/O and flush output.  If necesssary, output file
 * is truncated.
 */
static void
dd_close(void)
{

	if (cfunc == def)
		def_close();
	else if (cfunc == block)
		block_close();
	else if (cfunc == unblock)
		unblock_close();
	if (ddflags & C_OSYNC && out.dbcnt < out.dbsz) {
		(void)memset(out.dbp, 0, out.dbsz - out.dbcnt);
		out.dbcnt = out.dbsz;
	}
	/* If there are pending sparse blocks, make sure
	 * to write out the final block un-sparse
	 */
	if ((out.dbcnt == 0) && pending) {
		memset(out.db, 0, out.dbsz);
		out.dbcnt = out.dbsz;
		out.dbp = out.db + out.dbcnt;
		pending -= out.dbsz;
	}
	if (out.dbcnt)
		dd_out(1);

	/*
	 * Reporting nfs write error may be defered until next
	 * write(2) or close(2) system call.  So, we need to do an
	 * extra check.  If an output is stdout, the file structure
	 * may be shared among with other processes and close(2) just
	 * decreases the reference count.
	 */
	if (out.fd == STDOUT_FILENO && fsync(out.fd) == -1 && errno != EINVAL) {
		fprintf(stderr, "fsync stdout: %s\n", strerror(errno));
		exit(1);
		/* NOTREACHED */
	}
	if (close(out.fd) == -1) {
		fprintf(stderr, "close: %s\n", strerror(errno));
		exit(1);
		/* NOTREACHED */
	}
}

void
dd_out(int force)
{
	static int warned;
	int64_t cnt, n, nw;
	u_char *outp;

	/*
	 * Write one or more blocks out.  The common case is writing a full
	 * output block in a single write; increment the full block stats.
	 * Otherwise, we're into partial block writes.  If a partial write,
	 * and it's a character device, just warn.  If a tape device, quit.
	 *
	 * The partial writes represent two cases.  1: Where the input block
	 * was less than expected so the output block was less than expected.
	 * 2: Where the input block was the right size but we were forced to
	 * write the block in multiple chunks.  The original versions of dd(1)
	 * never wrote a block in more than a single write, so the latter case
	 * never happened.
	 *
	 * One special case is if we're forced to do the write -- in that case
	 * we play games with the buffer size, and it's usually a partial write.
	 */
	outp = out.db;
	for (n = force ? out.dbcnt : out.dbsz;; n = out.dbsz) {
		for (cnt = n;; cnt -= nw) {

			if (!force && ddflags & C_SPARSE) {
				int sparse, i;
				sparse = 1;	/* Is buffer sparse? */
				for (i = 0; i < cnt; i++)
					if (outp[i] != 0) {
						sparse = 0;
						break;
					}
				if (sparse) {
					pending += cnt;
					outp += cnt;
					nw = 0;
					break;
				}
			}
			if (pending != 0) {
				if (lseek(out.fd, pending, SEEK_CUR) ==
				    -1) {
					fprintf(stderr,
						"%s: seek error creating "
						"sparse file: %s\n",
						out.name, strerror(errno));
					exit(1);
				}
			}
			nw = bwrite(out.fd, outp, cnt);
			if (nw <= 0) {
				if (nw == 0) {
					fprintf(stderr, "%s: end of device\n",
						out.name);
					exit(1);
					/* NOTREACHED */
				}
				if (errno != EINTR) {
					fprintf(stderr, "%s: write error: %s\n",
						out.name, strerror(errno));
					/* NOTREACHED */
					exit(1);
				}
				nw = 0;
			}
			if (pending) {
				st.bytes += pending;
				st.sparse += pending/out.dbsz;
				st.out_full += pending/out.dbsz;
				pending = 0;
			}
			outp += nw;
			st.bytes += nw;
			if (nw == n) {
				if (n != (int64_t)out.dbsz)
					++st.out_part;
				else
					++st.out_full;
				break;
			}
			++st.out_part;
			if (nw == cnt)
				break;
			if (out.flags & ISCHR && !warned) {
				warned = 1;
				fprintf(stderr, "%s: short write on character "
					"device\n", out.name);
			}
			if (out.flags & ISTAPE) {
				fprintf(stderr,
					"%s: short write on tape device",
					out.name);
				exit(1);
				/* NOTREACHED */
			}
		}
		if ((out.dbcnt -= n) < out.dbsz)
			break;
	}

	/* Reassemble the output block. */
	if (out.dbcnt)
		(void)memmove(out.db, out.dbp - out.dbcnt, out.dbcnt);
	out.dbp = out.db + out.dbcnt;

	if (progress)
		(void)write(STDERR_FILENO, ".", 1);
}

/*
 * A protected against SIGINFO write
 */
ssize_t
bwrite(int fd, const void *buf, size_t len)
{
	sigset_t oset;
	ssize_t rv;
	int oerrno;

	(void)sigprocmask(SIG_BLOCK, &infoset, &oset);
	rv = write(fd, buf, len);
	oerrno = errno;
	(void)sigprocmask(SIG_SETMASK, &oset, NULL);
	errno = oerrno;
	return (rv);
}

/*
 * Position input/output data streams before starting the copy.  Device type
 * dependent.  Seekable devices use lseek, and the rest position by reading.
 * Seeking past the end of file can cause null blocks to be written to the
 * output.
 */
void
pos_in(void)
{
	int bcnt, cnt, nr, warned;

	/* If not a pipe or tape device, try to seek on it. */
	if (!(in.flags & (ISPIPE|ISTAPE))) {
		if (lseek64(in.fd,
		    (off64_t)in.offset * (off64_t)in.dbsz, SEEK_CUR) == -1) {
			fprintf(stderr, "%s: seek error: %s",
				in.name, strerror(errno));
			exit(1);
			/* NOTREACHED */
		}
		return;
		/* NOTREACHED */
	}

	/*
	 * Read the data.  If a pipe, read until satisfy the number of bytes
	 * being skipped.  No differentiation for reading complete and partial
	 * blocks for other devices.
	 */
	for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
		if ((nr = read(in.fd, in.db, bcnt)) > 0) {
			if (in.flags & ISPIPE) {
				if (!(bcnt -= nr)) {
					bcnt = in.dbsz;
					--cnt;
				}
			} else
				--cnt;
			continue;
		}

		if (nr == 0) {
			if (files_cnt > 1) {
				--files_cnt;
				continue;
			}
			fprintf(stderr, "skip reached end of input\n");
			exit(1);
			/* NOTREACHED */
		}

		/*
		 * Input error -- either EOF with no more files, or I/O error.
		 * If noerror not set die.  POSIX requires that the warning
		 * message be followed by an I/O display.
		 */
		if (ddflags & C_NOERROR) {
			if (!warned) {

				fprintf(stderr, "%s: error occurred\n",
					in.name);
				warned = 1;
				summary();
			}
			continue;
		}
		fprintf(stderr, "%s: read error: %s", in.name, strerror(errno));
		exit(1);
		/* NOTREACHED */
	}
}

void
pos_out(void)
{
/*	struct mtop t_op;        */
	int64_t cnt, n;

	/*
	 * If not a tape, try seeking on the file.  Seeking on a pipe is
	 * going to fail, but don't protect the user -- they shouldn't
	 * have specified the seek operand.
	 */
	if (!(out.flags & ISTAPE)) {
		if (lseek64(out.fd,
		    (off64_t)out.offset * (off64_t)out.dbsz, SEEK_SET) == -1) {
			fprintf(stderr, "%s: seek error: %s\n",
				out.name, strerror(errno));
			exit(1);
			/* NOTREACHED */
		}
		return;
	}

	/* If no read access, try using mtio. */
	if (out.flags & NOREAD) {
/*		t_op.mt_op = MTFSR;
		t_op.mt_count = out.offset;

		if (ioctl(out.fd, MTIOCTOP, &t_op) < 0)*/
			fprintf(stderr, "%s: cannot read", out.name);
			exit(1);
			/* NOTREACHED */
		return;
	}

	/* Read it. */
	for (cnt = 0; cnt < (int64_t)out.offset; ++cnt) {
		if ((n = read(out.fd, out.db, out.dbsz)) > 0)
			continue;

		if (n < 0) {
			fprintf(stderr, "%s: cannot position by reading: %s\n",
				out.name, strerror(errno));
			exit(1);
			/* NOTREACHED */
		}

		/*
		 * If reach EOF, fill with NUL characters; first, back up over
		 * the EOF mark.  Note, cnt has not yet been incremented, so
		 * the EOF read does not count as a seek'd block.
		 */
/*		t_op.mt_op = MTBSR;
		t_op.mt_count = 1;
		if (ioctl(out.fd, MTIOCTOP, &t_op) == -1) */ {
			fprintf(stderr, "%s: cannot position\n", out.name);
			exit(1);
			/* NOTREACHED */
		}

		while (cnt++ < (int64_t)out.offset)
			if ((n = bwrite(out.fd, out.db, out.dbsz)) != (int64_t)out.dbsz) {
				fprintf(stderr, "%s: cannot position "
					"by writing: %s\n",
					out.name, strerror(errno));
				exit(1);
				/* NOTREACHED */
			}
		break;
	}
}

/*
 * def --
 * Copy input to output.  Input is buffered until reaches obs, and then
 * output until less than obs remains.  Only a single buffer is used.
 * Worst case buffer calculation is (ibs + obs - 1).
 */
void
def(void)
{
	uint64_t cnt;
	u_char *inp;
	const u_char *t;

	if ((t = ctab) != NULL)
		for (inp = in.dbp - (cnt = in.dbrcnt); cnt--; ++inp)
			*inp = t[*inp];

	/* Make the output buffer look right. */
	out.dbp = in.dbp;
	out.dbcnt = in.dbcnt;

	if (in.dbcnt >= out.dbsz) {
		/* If the output buffer is full, write it. */
		dd_out(0);

		/*
		 * Ddout copies the leftover output to the beginning of
		 * the buffer and resets the output buffer.  Reset the
		 * input buffer to match it.
	 	 */
		in.dbp = out.dbp;
		in.dbcnt = out.dbcnt;
	}
}

void
def_close(void)
{
	if (ddflags & C_FDATASYNC) {
		fdatasync(out.fd);
	}

	/* Just update the count, everything is already in the buffer. */
	if (in.dbcnt)
		out.dbcnt = in.dbcnt;
}

#ifdef	NO_CONV
/* Build a smaller version (i.e. for a miniroot) */
/* These can not be called, but just in case...  */
static const char no_block[] = "unblock and -DNO_CONV?\n";
void block(void)		{ fprintf(stderr, "%s", no_block + 2); exit(1); }
void block_close(void)		{ fprintf(stderr, "%s", no_block + 2); exit(1); }
void unblock(void)		{ fprintf(stderr, "%s", no_block); exit(1); }
void unblock_close(void)	{ fprintf(stderr, "%s", no_block); exit(1); }
#else	/* NO_CONV */

/*
 * Copy variable length newline terminated records with a max size cbsz
 * bytes to output.  Records less than cbs are padded with spaces.
 *
 * max in buffer:  MAX(ibs, cbsz)
 * max out buffer: obs + cbsz
 */
void
block(void)
{
	static int intrunc;
	int ch = 0;	/* pacify gcc */
	uint64_t cnt, maxlen;
	u_char *inp, *outp;
	const u_char *t;

	/*
	 * Record truncation can cross block boundaries.  If currently in a
	 * truncation state, keep tossing characters until reach a newline.
	 * Start at the beginning of the buffer, as the input buffer is always
	 * left empty.
	 */
	if (intrunc) {
		for (inp = in.db, cnt = in.dbrcnt;
		    cnt && *inp++ != '\n'; --cnt);
		if (!cnt) {
			in.dbcnt = 0;
			in.dbp = in.db;
			return;
		}
		intrunc = 0;
		/* Adjust the input buffer numbers. */
		in.dbcnt = cnt - 1;
		in.dbp = inp + cnt - 1;
	}

	/*
	 * Copy records (max cbsz size chunks) into the output buffer.  The
	 * translation is done as we copy into the output buffer.
	 */
	for (inp = in.dbp - in.dbcnt, outp = out.dbp; in.dbcnt;) {
		maxlen = MIN(cbsz, in.dbcnt);
		if ((t = ctab) != NULL)
			for (cnt = 0;
			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
				*outp++ = t[ch];
		else
			for (cnt = 0;
			    cnt < maxlen && (ch = *inp++) != '\n'; ++cnt)
				*outp++ = ch;
		/*
		 * Check for short record without a newline.  Reassemble the
		 * input block.
		 */
		if (ch != '\n' && in.dbcnt < cbsz) {
			(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
			break;
		}

		/* Adjust the input buffer numbers. */
		in.dbcnt -= cnt;
		if (ch == '\n')
			--in.dbcnt;

		/* Pad short records with spaces. */
		if (cnt < cbsz)
			(void)memset(outp, ctab ? ctab[' '] : ' ', cbsz - cnt);
		else {
			/*
			 * If the next character wouldn't have ended the
			 * block, it's a truncation.
			 */
			if (!in.dbcnt || *inp != '\n')
				++st.trunc;

			/* Toss characters to a newline. */
			for (; in.dbcnt && *inp++ != '\n'; --in.dbcnt);
			if (!in.dbcnt)
				intrunc = 1;
			else
				--in.dbcnt;
		}

		/* Adjust output buffer numbers. */
		out.dbp += cbsz;
		if ((out.dbcnt += cbsz) >= out.dbsz)
			dd_out(0);
		outp = out.dbp;
	}
	in.dbp = in.db + in.dbcnt;
}

void
block_close(void)
{

	/*
	 * Copy any remaining data into the output buffer and pad to a record.
	 * Don't worry about truncation or translation, the input buffer is
	 * always empty when truncating, and no characters have been added for
	 * translation.  The bottom line is that anything left in the input
	 * buffer is a truncated record.  Anything left in the output buffer
	 * just wasn't big enough.
	 */
	if (in.dbcnt) {
		++st.trunc;
		(void)memmove(out.dbp, in.dbp - in.dbcnt, in.dbcnt);
		(void)memset(out.dbp + in.dbcnt,
		    ctab ? ctab[' '] : ' ', cbsz - in.dbcnt);
		out.dbcnt += cbsz;
	}
}

/*
 * Convert fixed length (cbsz) records to variable length.  Deletes any
 * trailing blanks and appends a newline.
 *
 * max in buffer:  MAX(ibs, cbsz) + cbsz
 * max out buffer: obs + cbsz
 */
void
unblock(void)
{
	uint64_t cnt;
	u_char *inp;
	const u_char *t;

	/* Translation and case conversion. */
	if ((t = ctab) != NULL)
		for (cnt = in.dbrcnt, inp = in.dbp - 1; cnt--; inp--)
			*inp = t[*inp];
	/*
	 * Copy records (max cbsz size chunks) into the output buffer.  The
	 * translation has to already be done or we might not recognize the
	 * spaces.
	 */
	for (inp = in.db; in.dbcnt >= cbsz; inp += cbsz, in.dbcnt -= cbsz) {
		for (t = inp + cbsz - 1; t >= inp && *t == ' '; --t);
		if (t >= inp) {
			cnt = t - inp + 1;
			(void)memmove(out.dbp, inp, cnt);
			out.dbp += cnt;
			out.dbcnt += cnt;
		}
		++out.dbcnt;
		*out.dbp++ = '\n';
		if (out.dbcnt >= out.dbsz)
			dd_out(0);
	}
	if (in.dbcnt)
		(void)memmove(in.db, in.dbp - in.dbcnt, in.dbcnt);
	in.dbp = in.db + in.dbcnt;
}

void
unblock_close(void)
{
	uint64_t cnt;
	u_char *t;

	if (in.dbcnt) {
		warnx("%s: short input record", in.name);
		for (t = in.db + in.dbcnt - 1; t >= in.db && *t == ' '; --t);
		if (t >= in.db) {
			cnt = t - in.db + 1;
			(void)memmove(out.dbp, in.db, cnt);
			out.dbp += cnt;
			out.dbcnt += cnt;
		}
		++out.dbcnt;
		*out.dbp++ = '\n';
	}
}

#endif	/* NO_CONV */

#define	tv2mS(tv) ((tv).tv_sec * 1000LL + ((tv).tv_usec + 500) / 1000)

void
summary(void)
{
	char buf[100];
	int64_t mS;
	struct timeval tv;

	if (progress)
		(void)write(STDERR_FILENO, "\n", 1);

	(void)gettimeofday(&tv, NULL);
	mS = tv2mS(tv) - tv2mS(st.start);
	if (mS == 0)
		mS = 1;
	/* Use snprintf(3) so that we don't reenter stdio(3). */
	(void)snprintf(buf, sizeof(buf),
	    "%llu+%llu records in\n%llu+%llu records out\n",
	    (unsigned long long)st.in_full,  (unsigned long long)st.in_part,
	    (unsigned long long)st.out_full, (unsigned long long)st.out_part);
	(void)write(STDERR_FILENO, buf, strlen(buf));
	if (st.swab) {
		(void)snprintf(buf, sizeof(buf), "%llu odd length swab %s\n",
		    (unsigned long long)st.swab,
		    (st.swab == 1) ? "block" : "blocks");
		(void)write(STDERR_FILENO, buf, strlen(buf));
	}
	if (st.trunc) {
		(void)snprintf(buf, sizeof(buf), "%llu truncated %s\n",
		    (unsigned long long)st.trunc,
		    (st.trunc == 1) ? "block" : "blocks");
		(void)write(STDERR_FILENO, buf, strlen(buf));
	}
	if (st.sparse) {
		(void)snprintf(buf, sizeof(buf), "%llu sparse output %s\n",
		    (unsigned long long)st.sparse,
		    (st.sparse == 1) ? "block" : "blocks");
		(void)write(STDERR_FILENO, buf, strlen(buf));
	}
	(void)snprintf(buf, sizeof(buf),
	    "%llu bytes transferred in %lu.%03d secs (%llu bytes/sec)\n",
	    (unsigned long long) st.bytes,
	    (long) (mS / 1000),
	    (int) (mS % 1000),
	    (unsigned long long) (st.bytes * 1000LL / mS));
	(void)write(STDERR_FILENO, buf, strlen(buf));
}

void
terminate(int notused)
{

	exit(0);
	/* NOTREACHED */
}

static int	c_arg(const void *, const void *);
#ifndef	NO_CONV
static int	c_conv(const void *, const void *);
#endif
static void	f_bs(char *);
static void	f_cbs(char *);
static void	f_conv(char *);
static void	f_count(char *);
static void	f_files(char *);
static void	f_ibs(char *);
static void	f_if(char *);
static void	f_obs(char *);
static void	f_of(char *);
static void	f_seek(char *);
static void	f_skip(char *);
static void	f_progress(char *);

static const struct arg {
	const char *name;
	void (*f)(char *);
	u_int set, noset;
} args[] = {
     /* the array needs to be sorted by the first column so
	bsearch() can be used to find commands quickly */
	{ "bs",		f_bs,		C_BS,	 C_BS|C_IBS|C_OBS|C_OSYNC },
	{ "cbs",	f_cbs,		C_CBS,	 C_CBS },
	{ "conv",	f_conv,		0,	 0 },
	{ "count",	f_count,	C_COUNT, C_COUNT },
	{ "files",	f_files,	C_FILES, C_FILES },
	{ "ibs",	f_ibs,		C_IBS,	 C_BS|C_IBS },
	{ "if",		f_if,		C_IF,	 C_IF },
	{ "obs",	f_obs,		C_OBS,	 C_BS|C_OBS },
	{ "of",		f_of,		C_OF,	 C_OF },
	{ "progress",	f_progress,	0,	 0 },
	{ "seek",	f_seek,		C_SEEK,	 C_SEEK },
	{ "skip",	f_skip,		C_SKIP,	 C_SKIP },
};

/*
 * args -- parse JCL syntax of dd.
 */
void
jcl(char **argv)
{
	struct arg *ap, tmp;
	char *oper, *arg;

	in.dbsz = out.dbsz = 512;

	while ((oper = *++argv) != NULL) {
		if ((arg = strchr(oper, '=')) == NULL) {
			fprintf(stderr, "unknown operand %s\n", oper);
			exit(1);
			/* NOTREACHED */
		}
		*arg++ = '\0';
		if (!*arg) {
			fprintf(stderr, "no value specified for %s\n", oper);
			exit(1);
			/* NOTREACHED */
		}
		tmp.name = oper;
		if (!(ap = (struct arg *)bsearch(&tmp, args,
		    sizeof(args)/sizeof(struct arg), sizeof(struct arg),
		    c_arg))) {
			fprintf(stderr, "unknown operand %s\n", tmp.name);
			exit(1);
			/* NOTREACHED */
		}
		if (ddflags & ap->noset) {
			fprintf(stderr,
			    "%s: illegal argument combination or already set\n",
			    tmp.name);
			exit(1);
			/* NOTREACHED */
		}
		ddflags |= ap->set;
		ap->f(arg);
	}

	/* Final sanity checks. */

	if (ddflags & C_BS) {
		/*
		 * Bs is turned off by any conversion -- we assume the user
		 * just wanted to set both the input and output block sizes
		 * and didn't want the bs semantics, so we don't warn.
		 */
		if (ddflags & (C_BLOCK | C_LCASE | C_SWAB | C_UCASE |
		    C_UNBLOCK | C_OSYNC | C_ASCII | C_EBCDIC | C_SPARSE)) {
			ddflags &= ~C_BS;
			ddflags |= C_IBS|C_OBS;
		}

		/* Bs supersedes ibs and obs. */
		if (ddflags & C_BS && ddflags & (C_IBS|C_OBS))
			fprintf(stderr, "bs supersedes ibs and obs\n");
	}

	/*
	 * Ascii/ebcdic and cbs implies block/unblock.
	 * Block/unblock requires cbs and vice-versa.
	 */
	if (ddflags & (C_BLOCK|C_UNBLOCK)) {
		if (!(ddflags & C_CBS)) {
			fprintf(stderr, "record operations require cbs\n");
			exit(1);
			/* NOTREACHED */
		}
		cfunc = ddflags & C_BLOCK ? block : unblock;
	} else if (ddflags & C_CBS) {
		if (ddflags & (C_ASCII|C_EBCDIC)) {
			if (ddflags & C_ASCII) {
				ddflags |= C_UNBLOCK;
				cfunc = unblock;
			} else {
				ddflags |= C_BLOCK;
				cfunc = block;
			}
		} else {
			fprintf(stderr,
			    "cbs meaningless if not doing record operations\n");
			exit(1);
			/* NOTREACHED */
		}
	} else
		cfunc = def;

	/* Read, write and seek calls take off_t as arguments.
	 *
	 * The following check is not done because an off_t is a quad
	 *  for current NetBSD implementations.
	 *
	 * if (in.offset > INT_MAX/in.dbsz || out.offset > INT_MAX/out.dbsz)
	 *	errx(1, "seek offsets cannot be larger than %d", INT_MAX);
	 */
}

static int
c_arg(const void *a, const void *b)
{

	return (strcmp(((const struct arg *)a)->name,
	    ((const struct arg *)b)->name));
}

static long long strsuftoll(const char* name, const char* arg, int def, unsigned long long max)
{
	long long result;
	
	if (sscanf(arg, "%lld", &result) == 0)
		result = def;
	return result;
}

static void
f_bs(char *arg)
{

	in.dbsz = out.dbsz = strsuftoll("block size", arg, 1, UINT_MAX);
}

static void
f_cbs(char *arg)
{

	cbsz = strsuftoll("conversion record size", arg, 1, UINT_MAX);
}

static void
f_count(char *arg)
{

	cpy_cnt = (uint64_t)strsuftoll("block count", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
	if (!cpy_cnt)
		terminate(0);
}

static void
f_files(char *arg)
{

	files_cnt = (u_int)strsuftoll("file count", arg, 0, UINT_MAX);
	if (!files_cnt)
		terminate(0);
}

static void
f_ibs(char *arg)
{

	if (!(ddflags & C_BS))
		in.dbsz = strsuftoll("input block size", arg, 1, UINT_MAX);
}

static void
f_if(char *arg)
{

	in.name = arg;
}

static void
f_obs(char *arg)
{

	if (!(ddflags & C_BS))
		out.dbsz = strsuftoll("output block size", arg, 1, UINT_MAX);
}

static void
f_of(char *arg)
{

	out.name = arg;
}

static void
f_seek(char *arg)
{

	out.offset = (uint64_t)strsuftoll("seek blocks", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
}

static void
f_skip(char *arg)
{

	in.offset = (uint64_t)strsuftoll("skip blocks", arg, 0, 0xFFFFFFFFFFFFFFFFULL);
}

static void
f_progress(char *arg)
{

	if (*arg != '0')
		progress = 1;
}

#ifdef	NO_CONV
/* Build a small version (i.e. for a ramdisk root) */
static void
f_conv(char *arg)
{

	fprintf(stderr, "conv option disabled\n");
	exit(1);
	/* NOTREACHED */
}
#else	/* NO_CONV */

static const struct conv {
	const char *name;
	u_int set, noset;
	const u_char *ctab;
} clist[] = {
	{ "block",	C_BLOCK,	C_UNBLOCK,	NULL },
	{ "fdatasync",	C_FDATASYNC,	0,		NULL },
	{ "noerror",	C_NOERROR,	0,		NULL },
	{ "notrunc",	C_NOTRUNC,	0,		NULL },
	{ "osync",	C_OSYNC,	C_BS,		NULL },
	{ "sparse",	C_SPARSE,	0,		NULL },
	{ "swab",	C_SWAB,		0,		NULL },
	{ "sync",	C_SYNC,		0,		NULL },
	{ "unblock",	C_UNBLOCK,	C_BLOCK,	NULL },
	/* If you add items to this table, be sure to add the
	 * conversions to the C_BS check in the jcl routine above.
	 */
};

static void
f_conv(char *arg)
{
	struct conv *cp, tmp;

	while (arg != NULL) {
		tmp.name = strsep(&arg, ",");
		if (!(cp = (struct conv *)bsearch(&tmp, clist,
		    sizeof(clist)/sizeof(struct conv), sizeof(struct conv),
		    c_conv))) {
			errx(EXIT_FAILURE, "unknown conversion %s", tmp.name);
			/* NOTREACHED */
		}
		if (ddflags & cp->noset) {
			errx(EXIT_FAILURE, "%s: illegal conversion combination", tmp.name);
			/* NOTREACHED */
		}
		ddflags |= cp->set;
		if (cp->ctab)
			ctab = cp->ctab;
	}
}

static int
c_conv(const void *a, const void *b)
{

	return (strcmp(((const struct conv *)a)->name,
	    ((const struct conv *)b)->name));
}

#endif	/* NO_CONV */


