/* 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 "busybox.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

extern int dd_main(int argc, char **argv)
{
	char *inFile = NULL;
	char *outFile = NULL;
	int inFd;
	int outFd;
	int inCc = 0;
	int outCc;
	int trunc=TRUE;
	int sync=FALSE;
	long blockSize = 512,ibs;
	uintmax_t skipBlocks = 0;
	uintmax_t seekBlocks = 0;
	uintmax_t count = (uintmax_t) - 1;
	uintmax_t inTotal = 0;
	uintmax_t outTotal = 0;
	uintmax_t totalSize;

	unsigned char buf[BUFSIZ];
	char *keyword = NULL;

	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 = atoi_w_units((strchr(*argv, '=')) + 1);
			if (count < 0) {
				error_msg("Bad count value %s\n", *argv);
				goto usage;
			}
		} else if (strncmp(*argv, "bs", 2) == 0) {
			blockSize = atoi_w_units((strchr(*argv, '=')) + 1);
			if (blockSize <= 0) {
				error_msg("Bad block size value %s\n", *argv);
				goto usage;
			}
		} else if (strncmp(*argv, "skip", 4) == 0) {
			skipBlocks = atoi_w_units((strchr(*argv, '=')) + 1);
			if (skipBlocks <= 0) {
				error_msg("Bad skip value %s\n", *argv);
				goto usage;
			}

		} else if (strncmp(*argv, "seek", 4) == 0) {
			seekBlocks = atoi_w_units((strchr(*argv, '=')) + 1);
			if (seekBlocks <= 0) {
				error_msg("Bad seek value %s\n", *argv);
				goto usage;
			}
		} else if (strncmp(*argv, "conv", 4) == 0) {
			keyword = (strchr(*argv, '=') + 1);
                	if (strcmp(keyword, "notrunc") == 0) 
				trunc=FALSE;
			if (strcmp(keyword, "sync") == 0) 
				sync=TRUE;
		} else {
			goto usage;
		}
		argc--;
		argv++;
	}

	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); */
		perror_msg_and_die("%s", inFile);
	}

	if (outFile == NULL)
		outFd = fileno(stdout);
	else
		outFd = open(outFile, O_WRONLY | O_CREAT, 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); */
		perror_msg_and_die("%s", outFile);
	}

	lseek(inFd, (off_t) (skipBlocks * blockSize), SEEK_SET);
	lseek(outFd, (off_t) (seekBlocks * blockSize), SEEK_SET);
	totalSize=count*blockSize;

	ibs=blockSize;
	if (ibs > BUFSIZ)
		ibs=BUFSIZ;
			
	while (totalSize > outTotal) {
		inCc = full_read(inFd, buf, ibs);
		inTotal += inCc;
		if ( (sync==TRUE) && (inCc>0) )
			while (inCc<ibs)
				buf[inCc++]='\0';

		if ((outCc = full_write(outFd, buf, inCc)) < 1){
			if (outCc < 0 ){
				perror("Error during write");
			}
			break;
		}
		outTotal += outCc;
        }
	if (trunc == TRUE) {
		ftruncate(outFd, lseek(outFd, 0, SEEK_CUR));
	}
	/* Note that we are not freeing memory or closing
	 * files here, to save a few bytes. */
#ifdef BB_FEATURE_CLEAN_UP
	close(inFd);
	close(outFd);
#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);
	return EXIT_SUCCESS;
  usage:

	usage(dd_usage);
}
