/* vi: set sw=4 ts=4: */
/*
 * Mini dd implementation for busybox
 *
 * Copyright (C) 1999, 2000 by Lineo, inc.
 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
 *
 * Based in part on code taken from sash. 
 *   Copyright (c) 1999 by David I. Bell
 *   Permission is granted to use, distribute, or modify this source,
 *   provided that this copyright notice remains intact.
 *
 * Permission to distribute this code under the GPL has been granted.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 *
 */


#include "internal.h"
#include <features.h>
#include <stdio.h>
#include <fcntl.h>
#include <errno.h>
#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
#include <inttypes.h>
#else
typedef unsigned long long int uintmax_t;
#endif

static const char dd_usage[] =
	"dd [if=FILE] [of=FILE] [bs=N] [count=N] [skip=N] [seek=N]\n"
#ifndef BB_FEATURE_TRIVIAL_HELP
	"\nCopy a file, converting and formatting according to options\n\n"
	"\tif=FILE\tread from FILE instead of stdin\n"
	"\tof=FILE\twrite to FILE instead of stdout\n"
	"\tbs=N\tread and write N bytes at a time\n"
	"\tcount=N\tcopy only N input blocks\n"
	"\tskip=N\tskip N input blocks\n"
	"\tseek=N\tskip N output blocks\n"
	"\n"
	"Numbers may be suffixed by w (x2), k (x1024), b (x512), or M (x1024^2)\n"
#endif
	;



extern int dd_main(int argc, char **argv)
{
	char *inFile = NULL;
	char *outFile = NULL;
	char *cp;
	int inFd;
	int outFd;
	int inCc = 0;
	int outCc;
	long blockSize = 512;
	uintmax_t skipBlocks = 0;
	uintmax_t seekBlocks = 0;
	uintmax_t count = (uintmax_t) - 1;
	uintmax_t intotal;
	uintmax_t outTotal;
	unsigned char *buf;

	argc--;
	argv++;

	/* Parse any options */
	while (argc) {
		if (inFile == NULL && (strncmp(*argv, "if", 2) == 0))
			inFile = ((strchr(*argv, '=')) + 1);
		else if (outFile == NULL && (strncmp(*argv, "of", 2) == 0))
			outFile = ((strchr(*argv, '=')) + 1);
		else if (strncmp("count", *argv, 5) == 0) {
			count = getNum((strchr(*argv, '=')) + 1);
			if (count <= 0) {
				fprintf(stderr, "Bad count value %s\n", *argv);
				goto usage;
			}
		} else if (strncmp(*argv, "bs", 2) == 0) {
			blockSize = getNum((strchr(*argv, '=')) + 1);
			if (blockSize <= 0) {
				fprintf(stderr, "Bad block size value %s\n", *argv);
				goto usage;
			}
		} else if (strncmp(*argv, "skip", 4) == 0) {
			skipBlocks = getNum((strchr(*argv, '=')) + 1);
			if (skipBlocks <= 0) {
				fprintf(stderr, "Bad skip value %s\n", *argv);
				goto usage;
			}

		} else if (strncmp(*argv, "seek", 4) == 0) {
			seekBlocks = getNum((strchr(*argv, '=')) + 1);
			if (seekBlocks <= 0) {
				fprintf(stderr, "Bad seek value %s\n", *argv);
				goto usage;
			}

		} else {
			goto usage;
		}
		argc--;
		argv++;
	}

	buf = xmalloc(blockSize);

	intotal = 0;
	outTotal = 0;

	if (inFile == NULL)
		inFd = fileno(stdin);
	else
		inFd = open(inFile, 0);

	if (inFd < 0) {
		/* Note that we are not freeing buf or closing
		 * files here to save a few bytes. This exits
		 * here anyways... */

		/* free(buf); */
		fatalError( inFile);
	}

	if (outFile == NULL)
		outFd = fileno(stdout);
	else
		outFd = open(outFile, O_WRONLY | O_CREAT | O_TRUNC, 0666);

	if (outFd < 0) {
		/* Note that we are not freeing buf or closing
		 * files here to save a few bytes. This exits
		 * here anyways... */

		/* close(inFd);
		   free(buf); */
		fatalError( outFile);
	}

	lseek(inFd, skipBlocks * blockSize, SEEK_SET);
	lseek(outFd, seekBlocks * blockSize, SEEK_SET);
	//
	//TODO: Convert to using fullRead & fullWrite
	// from utility.c
	//  -Erik
	while (outTotal < count * blockSize) {
		inCc = read(inFd, buf, blockSize);
		if (inCc < 0) {
			perror(inFile);
			goto cleanup;
		} else if (inCc == 0) {
			goto cleanup;
		}
		intotal += inCc;
		cp = buf;

		while (intotal > outTotal) {
			if (outTotal + inCc > count * blockSize)
				inCc = count * blockSize - outTotal;
			outCc = write(outFd, cp, inCc);
			if (outCc < 0) {
				perror(outFile);
				goto cleanup;
			} else if (outCc == 0) {
				goto cleanup;
			}

			inCc -= outCc;
			cp += outCc;
			outTotal += outCc;
		}
	}

	if (inCc < 0)
		perror(inFile);

  cleanup:
	/* Note that we are not freeing memory or closing
	 * files here, to save a few bytes. */
#if 0
	close(inFd);
	close(outFd);
	free(buf);
#endif

	printf("%ld+%d records in\n", (long) (intotal / blockSize),
		   (intotal % blockSize) != 0);
	printf("%ld+%d records out\n", (long) (outTotal / blockSize),
		   (outTotal % blockSize) != 0);
	exit(TRUE);
  usage:

	usage(dd_usage);
}
