#include #include #include #include #include #include #include #include #define RAND_SOURCE "/dev/urandom" unsigned int f_flag; unsigned int u_flag; unsigned int z_flag; unsigned int n_loops; int shred(int rand_fd, int fd) { /* Get size */ off_t size = lseek(fd, 0, SEEK_END); if (size <= 0) return 1; void *buf = mmap(NULL, size, PROT_WRITE, MAP_SHARED, fd, 0); if (buf == MAP_FAILED) { fprintf(stderr, "shred: mmap: %s\n", strerror(errno)); return 1; } for (unsigned int n = 0; n < n_loops; n++) { read(rand_fd, buf, size); fsync(fd); } if (z_flag) memset(buf, 0, size); if (munmap(buf, size)) { fprintf(stderr, "shred: munmap: %s\n", strerror(errno)); return 1; } 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], "--help")) { printf("shred [-n=N Overwrite N times (default 3)] [-z Final overwrite with zeros] [-u Remove file] [-f Chmod to ensure writability] [file file2...]\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; } for (; i < argc; i++) { int fd = open(argv[i], O_RDWR); if (fd < 0) { fprintf(stderr, "shred: %s is %s\n", argv[i], strerror(errno)); continue; } shred(rand_fd, fd); 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); return 0; }