#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=name] [of=name] [bs=n] [count=n]\n"
+"dd [if=name] [of=name] [bs=n] [count=n]\n\n"
"Copy 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 stout\n"
"\tcount=n\tcopy only n input blocks\n"
//"\tskip=n\tskip n input blocks\n"
"\n"
-"BYTES may be suffixed: by k for x1024, b for x512, and w for x2.\n";
-
-
-
-
-/*
- * Read a number with a possible multiplier.
- * Returns -1 if the number format is illegal.
- */
-static long getNum (const char *cp)
-{
- long value;
-
- if (!isDecimal (*cp))
- return -1;
-
- value = 0;
-
- while (isDecimal (*cp))
- value = value * 10 + *cp++ - '0';
-
- switch (*cp++) {
- case 'k':
- value *= 1024;
- break;
+"BYTES may be suffixed by w (x2), k (x1024), b (x512), or m (x1024^2).\n";
- case 'b':
- value *= 512;
- break;
-
- case 'w':
- value *= 2;
- break;
-
- case '\0':
- return value;
-
- default:
- return -1;
- }
-
- if (*cp)
- return -1;
-
- return value;
-}
extern int dd_main (int argc, char **argv)
{
- const char *inFile;
- const char *outFile;
+ const char *inFile = NULL;
+ const char *outFile = NULL;
char *cp;
int inFd;
int outFd;
int inCc = 0;
int outCc;
- int skipBlocks;
- int blockSize;
- long count;
- long intotal;
- long outTotal;
+ size_t blockSize = 512;
+ //uintmax_t skipBlocks = 0;
+ uintmax_t count = (uintmax_t)-1;
+ uintmax_t intotal;
+ uintmax_t outTotal;
unsigned char *buf;
- inFile = NULL;
- outFile = NULL;
- blockSize = 512;
- skipBlocks = 0;
- count = 1;
-
-
argc--;
argv++;
else if (strncmp("count", *argv, 5) == 0) {
count = getNum ((strchr(*argv, '='))+1);
if (count <= 0) {
- fprintf (stderr, "Bad count value %ld\n", count);
+ 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 %d\n", blockSize);
+ fprintf (stderr, "Bad block size value %s\n", *argv);
goto usage;
}
}
argc--;
argv++;
}
- if ( inFile == NULL || outFile == NULL)
- goto usage;
buf = malloc (blockSize);
if (buf == NULL) {
outTotal = 0;
if (inFile == NULL)
- inFd = STDIN;
+ inFd = fileno(stdin);
else
inFd = open (inFile, 0);
}
if (outFile == NULL)
- outFd = STDOUT;
+ outFd = fileno(stdout);
else
outFd = creat (outFile, 0666);
}
//lseek(inFd, skipBlocks*blockSize, SEEK_SET);
+ //
+ //TODO: Convert to using fullRead & fullWrite
+ // from utilitity.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;
if (outCc < 0) {
perror (outFile);
goto cleanup;
+ } else if (outCc == 0) {
+ goto cleanup;
}
inCc -= outCc;
close (outFd);
free (buf);
- printf ("%ld+%d records in\n", intotal / blockSize,
+ printf ("%ld+%d records in\n", (long)(intotal / blockSize),
(intotal % blockSize) != 0);
- printf ("%ld+%d records out\n", outTotal / blockSize,
+ printf ("%ld+%d records out\n", (long)(outTotal / blockSize),
(outTotal % blockSize) != 0);
exit( TRUE);
usage:
- fprintf (stderr, "%s", dd_usage);
- exit( FALSE);
+ usage( dd_usage);
}