1 /* vi: set sw=4 ts=4: */
3 * Mini dd implementation for busybox
6 * Copyright (C) 2000,2001 Matt Kraai
8 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.
13 static const struct suffix_mult dd_suffixes[] = {
26 static size_t out_full;
27 static size_t out_part;
28 static size_t in_full;
29 static size_t in_part;
31 static void dd_output_status(int cur_signal)
33 fprintf(stderr, "%ld+%ld records in\n%ld+%ld records out\n",
34 (long)in_full, (long)in_part,
35 (long)out_full, (long)out_part);
38 int dd_main(int argc, char **argv)
40 size_t count = -1, oc = 0, ibs = 512, obs = 512;
42 off_t seek = 0, skip = 0;
43 int sync_flag = FALSE, noerror = FALSE, trunc_flag = TRUE, twobufs_flag = 0,
45 const char *infile = NULL, *outfile = NULL;
48 if (ENABLE_FEATURE_DD_SIGNAL_HANDLING)
52 memset(&sa, 0, sizeof(sa));
53 sa.sa_handler = dd_output_status;
54 sa.sa_flags = SA_RESTART;
55 sigemptyset(&sa.sa_mask);
56 sigaction(SIGUSR1, &sa, 0);
59 for (i = 1; i < argc; i++) {
60 if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("ibs=", argv[i], 4)) {
61 ibs = bb_xparse_number(argv[i]+4, dd_suffixes);
63 } else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("obs=", argv[i], 4)) {
64 obs = bb_xparse_number(argv[i]+4, dd_suffixes);
66 } else if (!strncmp("bs=", argv[i], 3)) {
67 ibs = obs = bb_xparse_number(argv[i]+3, dd_suffixes);
68 } else if (!strncmp("count=", argv[i], 6))
69 count = bb_xparse_number(argv[i]+6, dd_suffixes);
70 else if (!strncmp("seek=", argv[i], 5))
71 seek = bb_xparse_number(argv[i]+5, dd_suffixes);
72 else if (!strncmp("skip=", argv[i], 5))
73 skip = bb_xparse_number(argv[i]+5, dd_suffixes);
74 else if (!strncmp("if=", argv[i], 3))
76 else if (!strncmp("of=", argv[i], 3))
78 else if (ENABLE_FEATURE_DD_IBS_OBS && !strncmp("conv=", argv[i], 5)) {
81 if (!strncmp("notrunc", ibuf, 7)) {
84 } else if (!strncmp("sync", ibuf, 4)) {
87 } else if (!strncmp("noerror", ibuf, 7)) {
91 bb_error_msg_and_die(bb_msg_invalid_arg, argv[i]+5, "conv");
93 if (ibuf[0] == '\0') break;
94 if (ibuf[0] == ',') ibuf++;
101 if (twobufs_flag) obuf = xmalloc(obs);
104 if (infile != NULL) {
105 ifd = xopen(infile, O_RDONLY);
108 infile = bb_msg_standard_input;
111 if (outfile != NULL) {
112 oflag = O_WRONLY | O_CREAT;
114 if (!seek && trunc_flag) {
118 ofd = xopen3(outfile, oflag, 0666);
120 if (seek && trunc_flag) {
121 if (ftruncate(ofd, seek * obs) < 0) {
124 if (fstat (ofd, &st) < 0 || S_ISREG (st.st_mode) ||
125 S_ISDIR (st.st_mode)) {
126 bb_perror_msg_and_die("%s", outfile);
132 outfile = bb_msg_standard_output;
136 if (lseek(ifd, skip * ibs, SEEK_CUR) < 0) {
138 n = safe_read(ifd, ibuf, ibs);
140 bb_perror_msg_and_die("%s", infile);
148 if (lseek(ofd, seek * obs, SEEK_CUR) < 0) {
149 bb_perror_msg_and_die("%s", outfile);
153 while (in_full + in_part != count) {
155 /* Pre-zero the buffer when doing the noerror thing */
156 memset(ibuf, '\0', ibs);
159 n = safe_read(ifd, ibuf, ibs);
166 bb_perror_msg("%s", infile);
168 bb_perror_msg_and_die("%s", infile);
171 if ((size_t)n == ibs) {
176 memset(ibuf + n, '\0', ibs - n);
186 memcpy(obuf + oc, tmp, d);
191 xwrite(ofd, obuf, obs);
197 xwrite(ofd, ibuf, n);
198 if (n == ibs) out_full++;
203 if (ENABLE_FEATURE_DD_IBS_OBS && oc) {
204 xwrite(ofd, obuf, oc);
207 if (close (ifd) < 0) {
208 bb_perror_msg_and_die("%s", infile);
211 if (close (ofd) < 0) {
212 bb_perror_msg_and_die("%s", outfile);