2 * Copyright (c) 1999 by David I. Bell
3 * Permission is granted to use, distribute, or modify this source,
4 * provided that this copyright notice remains intact.
6 * The "dd" command, originally taken from sash.
8 * Permission to distribute this code under the GPL has been granted.
9 * Mostly rewritten and bugs fixed for busybox by Erik Andersen <andersee@debian.org>
17 const char dd_usage[] =
18 "Copy a file, converting and formatting according to options\n\
20 usage: [if=name] [of=name] [bs=n] [count=n]\n\
21 \tif=FILE\tread from FILE instead of stdin\n\
22 \tof=FILE\twrite to FILE instead of stout\n\
23 \tbs=n\tread and write N bytes at a time\n\
24 \tcount=n\tcopy only n input blocks\n\
25 \tskip=n\tskip n input blocks\n\
27 BYTES may be suffixed: by k for x1024, b for x512, and w for x2.\n";
33 * Read a number with a possible multiplier.
34 * Returns -1 if the number format is illegal.
36 static long getNum (const char *cp)
45 while (isDecimal (*cp))
46 value = value * 10 + *cp++ - '0';
75 extern int dd_main (int argc, char **argv)
101 /* Parse any options */
103 if (inFile == NULL && (strncmp("if", *argv, 2) == 0))
105 else if (outFile == NULL && (strncmp("of", *argv, 2) == 0))
107 else if (strncmp("count", *argv, 5) == 0) {
108 count = getNum (*argv);
110 fprintf (stderr, "Bad count value %ld\n", count);
114 else if (strncmp("bs", *argv, 2) == 0) {
115 blockSize = getNum(*argv);
116 if (blockSize <= 0) {
117 fprintf (stderr, "Bad block size value %d\n", blockSize);
121 else if (strncmp("skip", *argv, 4) == 0) {
122 skipBlocks = atoi( *argv);
123 if (skipBlocks <= 0) {
124 fprintf (stderr, "Bad skip value %d\n", skipBlocks);
130 fprintf (stderr, "Got here. argv=%s\n", *argv);
137 if ( inFile == NULL || outFile == NULL)
140 buf = malloc (blockSize);
142 fprintf (stderr, "Cannot allocate buffer\n");
152 inFd = open (inFile, 0);
163 outFd = creat (outFile, 0666);
172 lseek(inFd, skipBlocks*blockSize, SEEK_SET);
173 while (outTotal < count * blockSize) {
174 inCc = read (inFd, buf, blockSize);
182 while (intotal > outTotal) {
183 if (outTotal + inCc > count * blockSize)
184 inCc = count * blockSize - outTotal;
185 outCc = write (outFd, cp, inCc);
205 printf ("%ld+%d records in\n", intotal / blockSize,
206 (intotal % blockSize) != 0);
207 printf ("%ld+%d records out\n", outTotal / blockSize,
208 (outTotal % blockSize) != 0);
212 fprintf (stderr, "%s", dd_usage);