summaryrefslogtreecommitdiff
path: root/command/dd.c
diff options
context:
space:
mode:
Diffstat (limited to 'command/dd.c')
-rw-r--r--command/dd.c63
1 files changed, 63 insertions, 0 deletions
diff --git a/command/dd.c b/command/dd.c
new file mode 100644
index 0000000..67f8be3
--- /dev/null
+++ b/command/dd.c
@@ -0,0 +1,63 @@
+#include "command.h"
+#include "lslib.h"
+
+#include <stdlib.h>
+
+static void help(void) {
+ printf("Usage: dd [if=FILE] [of=FILE] [bs=N] [count=N]\n\n");
+ printf("Copy a file with converting and formatting\n\n");
+ printf("\tif=FILE\t\tRead from FILE instead of stdin\n");
+ printf("\tof=FILE\t\tWrite to FILE instead of stdout\n");
+ printf("\tbs=N\t\tRead and write N bytes at a time\n");
+ printf("\tcount=N\t\tCopy only N input blocks\n");
+}
+
+COMMAND(dd) {
+
+ FILE* in_file = stdin;
+ FILE* out_file = stdout;
+ int bs = 1024;
+ int count = -1;
+ int i;
+ char* buffer;
+ size_t read;
+
+ parse_help(argc, argv, help);
+
+ for (i = 0; i < argc; i++) {
+ if (prefix("if=", argv[i])) {
+ char* path = argv[i] + 3;
+ in_file = get_file(path, "rb");
+ } else if (prefix("of=", argv[i])) {
+ char* path = argv[i] + 3;
+ out_file = get_file(path, "wb");
+ } else if (prefix("bs=", argv[i])) {
+ char* str = argv[i] + 3;
+ bs = get_number(str);
+ if (bs < 1) {
+ error("block size must be greater than 0");
+ }
+ } else if (prefix("count=", argv[i])) {
+ char* str = argv[i] + 6;
+ count = get_number(str);
+ if (count < 1) {
+ error("count must be greather than 0");
+ }
+ } else {
+ error("unkown option %s", argv[i]);
+ }
+ }
+
+ buffer = malloc(bs);
+
+ while ((read = fread(buffer, 1, bs, in_file)) != 0) {
+ fwrite(buffer, 1, read, out_file);
+ if (--count, count == 0) break;
+ }
+
+ free(buffer);
+ fclose(in_file);
+ fclose(out_file);
+
+ return EXIT_SUCCESS;
+}