lazysphere/command/dd.c

81 lines
2.5 KiB
C
Raw Normal View History

2023-06-08 01:33:44 +00:00
/**
* file: dd.c
* command: dd
* author: Tyler Murphy
*/
2023-05-06 04:39:44 +00:00
#include "command.h"
#include "lslib.h"
#include <stdlib.h>
2023-04-27 18:38:16 +00:00
2023-06-08 01:33:44 +00:00
/**
* Help function for dd
*/
2023-05-01 22:43:32 +00:00
static void help(void) {
2023-04-27 18:38:16 +00:00
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");
2023-04-27 18:38:16 +00:00
}
2023-06-08 01:33:44 +00:00
/**
* Copys a file with converting and formatting
*/
2023-05-15 14:57:33 +00:00
COMMAND(dd_main) {
2023-04-27 18:38:16 +00:00
2023-06-08 01:33:44 +00:00
FILE* in_file = stdin; /* the file to copy from */
FILE* out_file = stdout; /* the file to copy to */
int bs = 1024; /* the default bs */
int count = -1; /* amount of bs's to copy, if negative go until EOF */
2023-05-04 20:10:37 +00:00
int i;
2023-06-08 01:33:44 +00:00
char* buffer; /* buffer to hold copy data */
2023-05-04 20:10:37 +00:00
size_t read;
2023-04-27 18:38:16 +00:00
2023-06-08 01:33:44 +00:00
/* parse arguments and only check for --help */
2023-05-01 22:43:32 +00:00
parse_help(argc, argv, help);
2023-06-08 01:33:44 +00:00
/* dd doesnt use standard arguments, parse though each argument and match each arg */
2023-05-04 20:10:37 +00:00
for (i = 0; i < argc; i++) {
2023-06-08 01:33:44 +00:00
if (prefix("if=", argv[i])) { /* sets the input file */
char* path = argv[i] + 3; /* get data after = */
2023-04-27 18:38:16 +00:00
in_file = get_file(path, "rb");
2023-06-08 01:33:44 +00:00
} else if (prefix("of=", argv[i])) { /* sets the output file */
char* path = argv[i] + 3; /* get data after = */
2023-04-27 18:38:16 +00:00
out_file = get_file(path, "wb");
2023-06-08 01:33:44 +00:00
} else if (prefix("bs=", argv[i])) { /* sets the blocksize */
char* str = argv[i] + 3; /* get data after = */
bs = get_blkm(str);
if (bs < 1) { /* cannot have a negative bs */
2023-05-03 16:17:56 +00:00
error("block size must be greater than 0");
2023-04-27 18:38:16 +00:00
}
2023-06-08 01:33:44 +00:00
} else if (prefix("count=", argv[i])) { /* sets the count of bs to do */
char* str = argv[i] + 6; /* get data after = */
2023-04-27 18:38:16 +00:00
count = get_number(str);
if (count < 1) {
2023-05-03 16:17:56 +00:00
error("count must be greather than 0");
2023-04-27 18:38:16 +00:00
}
2023-06-08 01:33:44 +00:00
} else { /* error and exit since arg is invalid */
2023-05-03 16:17:56 +00:00
error("unkown option %s", argv[i]);
2023-04-27 18:38:16 +00:00
}
}
2023-06-08 01:33:44 +00:00
/* allocate buffer of set bs */
2023-05-15 01:43:02 +00:00
buffer = xalloc(bs);
2023-05-04 20:10:37 +00:00
2023-06-08 01:33:44 +00:00
/* read data until EOF from and to buf */
2023-04-27 18:38:16 +00:00
while ((read = fread(buffer, 1, bs, in_file)) != 0) {
fwrite(buffer, 1, read, out_file);
if (--count, count == 0) break;
}
2023-06-08 01:33:44 +00:00
/* cleanup */
2023-04-27 18:38:16 +00:00
free(buffer);
fclose(in_file);
fclose(out_file);
return EXIT_SUCCESS;
}