aboutsummaryrefslogtreecommitdiff
path: root/dd.c
diff options
context:
space:
mode:
authorkraai <kraai@69ca8d6d-28ef-0310-b511-8ec308f3f277>2000-12-18 21:38:57 +0000
committerkraai <kraai@69ca8d6d-28ef-0310-b511-8ec308f3f277>2000-12-18 21:38:57 +0000
commit4c21208328fef24301dc80943a4fee9c1b5c56ac (patch)
tree333d1ef43d092edd4b41030112cb71559bf9cb3a /dd.c
parent6544fa28e7e5ff0df19d62ef0a872f523bd32faa (diff)
downloadbusybox-w32-4c21208328fef24301dc80943a4fee9c1b5c56ac.tar.gz
busybox-w32-4c21208328fef24301dc80943a4fee9c1b5c56ac.tar.bz2
busybox-w32-4c21208328fef24301dc80943a4fee9c1b5c56ac.zip
Rewrote dd.
git-svn-id: svn://busybox.net/trunk/busybox@1469 69ca8d6d-28ef-0310-b511-8ec308f3f277
Diffstat (limited to 'dd.c')
-rw-r--r--dd.c243
1 files changed, 105 insertions, 138 deletions
diff --git a/dd.c b/dd.c
index 626b54898..a0d2330ea 100644
--- a/dd.c
+++ b/dd.c
@@ -2,15 +2,8 @@
2/* 2/*
3 * Mini dd implementation for busybox 3 * Mini dd implementation for busybox
4 * 4 *
5 * Copyright (C) 1999, 2000 by Lineo, inc.
6 * Written by Erik Andersen <andersen@lineo.com>, <andersee@debian.org>
7 * 5 *
8 * Based in part on code taken from sash. 6 * Copyright (C) 2000 by Matt Kraai <kraai@alumni.carnegiemellon.edu>
9 * Copyright (c) 1999 by David I. Bell
10 * Permission is granted to use, distribute, or modify this source,
11 * provided that this copyright notice remains intact.
12 *
13 * Permission to distribute this code under the GPL has been granted.
14 * 7 *
15 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -28,154 +21,128 @@
28 * 21 *
29 */ 22 */
30 23
31
32#include "busybox.h" 24#include "busybox.h"
33#include <features.h> 25
34#include <stdio.h> 26#include <sys/types.h>
35#include <fcntl.h> 27#include <fcntl.h>
36#include <errno.h>
37#if (__GLIBC__ >= 2) && (__GLIBC_MINOR__ >= 1)
38#include <inttypes.h>
39#else
40typedef unsigned long long int uintmax_t;
41#endif
42 28
43extern int dd_main(int argc, char **argv) 29static struct suffix_mult dd_suffixes[] = {
30 { "c", 1 },
31 { "w", 2 },
32 { "b", 512 },
33 { "kD", 1000 },
34 { "k", 1024 },
35 { "MD", 1000000 },
36 { "M", 1048576 },
37 { "GD", 1000000000 },
38 { "G", 1073741824 },
39 { NULL, 0 }
40};
41
42int dd_main(int argc, char **argv)
44{ 43{
45 char *inFile = NULL; 44 int i, ifd, ofd, sync = FALSE, trunc = TRUE;
46 char *outFile = NULL; 45 size_t in_full = 0, in_part = 0, out_full = 0, out_part = 0;
47 int inFd; 46 size_t bs = 512, count = -1;
48 int outFd; 47 ssize_t n;
49 int inCc = 0; 48 off_t seek = 0, skip = 0;
50 int outCc; 49 FILE *statusfp;
51 int trunc=TRUE; 50 char *infile = NULL, *outfile = NULL, *buf;
52 int sync=FALSE; 51
53 long blockSize = 512,ibs; 52 for (i = 1; i < argc; i++) {
54 uintmax_t skipBlocks = 0; 53 if (strncmp("bs=", argv[i], 3) == 0)
55 uintmax_t seekBlocks = 0; 54 bs = parse_number(argv[i]+3, dd_suffixes);
56 uintmax_t count = (uintmax_t) - 1; 55 else if (strncmp("count=", argv[i], 6) == 0)
57 uintmax_t inTotal = 0; 56 count = parse_number(argv[i]+6, dd_suffixes);
58 uintmax_t outTotal = 0; 57 else if (strncmp("seek=", argv[i], 5) == 0)
59 uintmax_t totalSize; 58 seek = parse_number(argv[i]+5, dd_suffixes);
60 59 else if (strncmp("skip=", argv[i], 5) == 0)
61 unsigned char buf[BUFSIZ]; 60 skip = parse_number(argv[i]+5, dd_suffixes);
62 char *keyword = NULL; 61 else if (strncmp("if=", argv[i], 3) == 0)
63 62 infile = argv[i]+3;
64 argc--; 63 else if (strncmp("of=", argv[i], 3) == 0)
65 argv++; 64 outfile = argv[i]+3;
66 65 else if (strncmp("conv=", argv[i], 5) == 0) {
67 /* Parse any options */ 66 buf = argv[i]+5;
68 while (argc) { 67 while (1) {
69 if (inFile == NULL && (strncmp(*argv, "if", 2) == 0)) 68 if (strncmp("notrunc", buf, 7) == 0) {
70 inFile = ((strchr(*argv, '=')) + 1); 69 trunc = FALSE;
71 else if (outFile == NULL && (strncmp(*argv, "of", 2) == 0)) 70 buf += 7;
72 outFile = ((strchr(*argv, '=')) + 1); 71 } else if (strncmp("sync", buf, 4) == 0) {
73 else if (strncmp("count", *argv, 5) == 0) { 72 sync = TRUE;
74 count = atoi_w_units((strchr(*argv, '=')) + 1); 73 buf += 4;
75 if (count < 0) { 74 } else {
76 error_msg("Bad count value %s\n", *argv); 75 error_msg_and_die("invalid conversion `%s'\n", argv[i]+5);
77 goto usage; 76 }
78 } 77 if (buf[0] == '\0')
79 } else if (strncmp(*argv, "bs", 2) == 0) { 78 break;
80 blockSize = atoi_w_units((strchr(*argv, '=')) + 1); 79 if (buf[0] == ',')
81 if (blockSize <= 0) { 80 buf++;
82 error_msg("Bad block size value %s\n", *argv);
83 goto usage;
84 }
85 } else if (strncmp(*argv, "skip", 4) == 0) {
86 skipBlocks = atoi_w_units((strchr(*argv, '=')) + 1);
87 if (skipBlocks <= 0) {
88 error_msg("Bad skip value %s\n", *argv);
89 goto usage;
90 }
91
92 } else if (strncmp(*argv, "seek", 4) == 0) {
93 seekBlocks = atoi_w_units((strchr(*argv, '=')) + 1);
94 if (seekBlocks <= 0) {
95 error_msg("Bad seek value %s\n", *argv);
96 goto usage;
97 } 81 }
98 } else if (strncmp(*argv, "conv", 4) == 0) { 82 } else
99 keyword = (strchr(*argv, '=') + 1); 83 usage(dd_usage);
100 if (strcmp(keyword, "notrunc") == 0)
101 trunc=FALSE;
102 if (strcmp(keyword, "sync") == 0)
103 sync=TRUE;
104 } else {
105 goto usage;
106 }
107 argc--;
108 argv++;
109 } 84 }
110 85
111 if (inFile == NULL) 86 buf = xmalloc(bs);
112 inFd = fileno(stdin);
113 else
114 inFd = open(inFile, 0);
115
116 if (inFd < 0) {
117 /* Note that we are not freeing buf or closing
118 * files here to save a few bytes. This exits
119 * here anyways... */
120 87
121 /* free(buf); */ 88 if (infile != NULL) {
122 perror_msg_and_die("%s", inFile); 89 if ((ifd = open(infile, O_RDONLY)) < 0)
90 perror_msg_and_die("%s", infile);
91 } else {
92 ifd = STDIN_FILENO;
93 infile = "standard input";
123 } 94 }
124 95
125 if (outFile == NULL) 96 if (outfile != NULL) {
126 outFd = fileno(stdout); 97 if ((ofd = open(outfile, O_WRONLY | O_CREAT, 0666)) < 0)
127 else 98 perror_msg_and_die("%s", outfile);
128 outFd = open(outFile, O_WRONLY | O_CREAT, 0666); 99 statusfp = stdout;
129 100 } else {
130 if (outFd < 0) { 101 ofd = STDOUT_FILENO;
131 /* Note that we are not freeing buf or closing 102 outfile = "standard output";
132 * files here to save a few bytes. This exits 103 statusfp = stderr;
133 * here anyways... */ 104 }
134 105
135 /* close(inFd); 106 if (skip) {
136 free(buf); */ 107 if (lseek(ifd, skip * bs, SEEK_CUR) < 0)
137 perror_msg_and_die("%s", outFile); 108 perror_msg_and_die("%s", infile);
138 } 109 }
139 110
140 lseek(inFd, (off_t) (skipBlocks * blockSize), SEEK_SET); 111 if (seek) {
141 lseek(outFd, (off_t) (seekBlocks * blockSize), SEEK_SET); 112 if (lseek(ofd, seek * bs, SEEK_CUR) < 0)
142 totalSize=count*blockSize; 113 perror_msg_and_die("%s", outfile);
114 }
143 115
144 ibs=blockSize; 116 if (trunc) {
145 if (ibs > BUFSIZ) 117 if (ftruncate(ofd, seek * bs) < 0)
146 ibs=BUFSIZ; 118 perror_msg_and_die("%s", outfile);
147 119 }
148 while (totalSize > outTotal) {
149 inCc = full_read(inFd, buf, ibs);
150 inTotal += inCc;
151 if ( (sync==TRUE) && (inCc>0) )
152 while (inCc<ibs)
153 buf[inCc++]='\0';
154 120
155 if ((outCc = full_write(outFd, buf, inCc)) < 1){ 121 while (in_full + in_part != count) {
156 if (outCc < 0 ){ 122 n = safe_read(ifd, buf, bs);
157 perror("Error during write"); 123 if (n < 0)
158 } 124 perror_msg_and_die("%s", infile);
125 if (n == 0)
159 break; 126 break;
127 if (n == bs)
128 in_full++;
129 else
130 in_part++;
131 if (sync) {
132 memset(buf + n, '\0', bs - n);
133 n = bs;
160 } 134 }
161 outTotal += outCc; 135 n = full_write(ofd, buf, n);
162 } 136 if (n < 0)
163 if (trunc == TRUE) { 137 perror_msg_and_die("%s", outfile);
164 ftruncate(outFd, lseek(outFd, 0, SEEK_CUR)); 138 if (n == bs)
139 out_full++;
140 else
141 out_part++;
165 } 142 }
166 /* Note that we are not freeing memory or closing
167 * files here, to save a few bytes. */
168#ifdef BB_FEATURE_CLEAN_UP
169 close(inFd);
170 close(outFd);
171#endif
172 143
173 printf("%ld+%d records in\n", (long) (inTotal / blockSize), 144 fprintf(statusfp, "%d+%d records in\n", in_full, in_part);
174 (inTotal % blockSize) != 0); 145 fprintf(statusfp, "%d+%d records out\n", out_full, out_part);
175 printf("%ld+%d records out\n", (long) (outTotal / blockSize),
176 (outTotal % blockSize) != 0);
177 return EXIT_SUCCESS;
178 usage:
179 146
180 usage(dd_usage); 147 return EXIT_SUCCESS;
181} 148}