diff --git a/TODO b/TODO index 9f4003e..1329940 100644 --- a/TODO +++ b/TODO @@ -4,8 +4,6 @@ printf shuf id ln -cp -shred du df dd diff --git a/coreutils/shred.c b/coreutils/shred.c new file mode 100644 index 0000000..9794257 --- /dev/null +++ b/coreutils/shred.c @@ -0,0 +1,109 @@ +#include +#include +#include +#include +#include +#include +#include + +#define RAND_SOURCE "/dev/urandom" +#define ZERO_SOURCE "/dev/zero" + +unsigned int f_flag; +unsigned int u_flag; +unsigned int z_flag; +unsigned int n_loops; + +int shred(int rand_fd, int zero_fd, int fd, unsigned int iter) { + off_t size = lseek(fd, 0, SEEK_END); + if (size < 0) + return 1; + + lseek(fd, 0, SEEK_SET); + + char buf[1]; + while (size) { + if (iter == n_loops && z_flag) + read(zero_fd, buf, sizeof(buf)); + + else + read(rand_fd, buf, sizeof(buf)); + + write(fd, buf, sizeof(buf)); + size--; + } + + fsync(fd); + return 0; +} + +int main(const int argc, const char **argv) { + n_loops = 3; + int i; + + for (i = 1; i < argc; i++) { + if (argv[i][0] != '-') + break; + + else if (!strcmp(argv[i], "-f")) + f_flag = 1; + + else if (!strcmp(argv[i], "-u")) + u_flag = 1; + + else if (!strcmp(argv[i], "-z")) + z_flag = 1; + + else if (!strncmp(argv[i], "-n=", 3)) { + char *val = strchr(argv[i], '='); + if (!val) + break; + + val[0] = '\0'; + n_loops = atoi(val + 1); + } + + else if (!strcmp(argv[i], "-h")) { + printf("shred [-n=N (Overwrite N times (default 3))] [-z (Final overwrite with zeros)] [-u (Remove file)] [-f (Chmod to ensure writability)] [FILE...]\n"); + return 1; + } + } + + + int rand_fd = open(RAND_SOURCE, O_RDONLY); + if (rand_fd < 0) { + fprintf(stderr, "shred: %s is %s\n", RAND_SOURCE, strerror(errno)); + return 1; + } + + int zero_fd = open(ZERO_SOURCE, O_RDONLY); + if (zero_fd < 0) { + fprintf(stderr, "shred: %s is %s\n", ZERO_SOURCE, strerror(errno)); + return 1; + } + + for (; i < argc; i++) { + int fd = open(argv[i], O_WRONLY); + if (fd < 0) { + fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno)); + continue; + } + + for (unsigned int n = 0; n <= n_loops; n++) + shred(rand_fd, zero_fd, fd, n); + + close(fd); + + if (u_flag) + if (unlink(argv[i]) < 0) + fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno)); + + if (f_flag) + if (chmod(argv[i], 0) < 0) + fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno)); + } + + close(rand_fd); + close(zero_fd); + return 0; +}