2023-04-27 18:38:16 +00:00
|
|
|
#include "../command.h"
|
|
|
|
#include <stdio.h>
|
|
|
|
|
|
|
|
static void help() {
|
|
|
|
printf("Usage: dd [if=FILE] [of=FILE] [bs=N] [count=N]\n\n");
|
|
|
|
printf("Copy a file with converting and formatting\n\n");
|
|
|
|
printf("if=FILE\t\tRead from FILE instead of stdin\n");
|
2023-04-27 23:13:40 +00:00
|
|
|
printf("of=FILE\t\tWrite to FILE instead of stdout\n");
|
|
|
|
printf("bs=N\t\tRead and write N bytes at a time\n");
|
|
|
|
printf("count=N\t\tCopy only N input blocks\n");
|
2023-04-27 18:38:16 +00:00
|
|
|
exit(EXIT_SUCCESS);
|
|
|
|
}
|
|
|
|
|
|
|
|
COMMAND(dd) {
|
|
|
|
|
|
|
|
FILE* in_file = stdin;
|
|
|
|
FILE* out_file = stdout;
|
|
|
|
int bs = 1024;
|
|
|
|
int count = -1;
|
|
|
|
|
|
|
|
for (int 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("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("error: count must be greather than 0");
|
|
|
|
}
|
|
|
|
} else if (streql("--help", argv[i])) {
|
|
|
|
help();
|
|
|
|
} else {
|
|
|
|
error("error: unkown option %s", argv[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
char* buffer = malloc(bs);
|
|
|
|
size_t read;
|
|
|
|
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;
|
|
|
|
}
|