From c28bcc04f41f6b70e43fff87959ecf819388064c Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Thu, 26 Jun 2014 21:55:31 +0200 Subject: wipe-sectors: wipe sectors which are non-zero --- wipe-sectors.c | 98 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 wipe-sectors.c diff --git a/wipe-sectors.c b/wipe-sectors.c new file mode 100644 index 0000000..cac0028 --- /dev/null +++ b/wipe-sectors.c @@ -0,0 +1,98 @@ +/* Reads a block device and wipe a block if non-zero. + * Author: Peter Wu + * Date: 2014-06-26 + */ +#include +#include +#include +#include +#include + +#define BUFSIZE (1024 * 1024 * 2) + +static char zeroes[BUFSIZE]; + +static void wipe(int fd, size_t len) { + off_t pos; + ssize_t r; + + pos = lseek(fd, -len, SEEK_CUR); + if (pos == (off_t) -1) + err(1, "failed to seek before write"); + + r = write(fd, zeroes, len); + if (r < 0) + err(1, "failed to write zeroes"); + if ((size_t) r != len) + errx(1, "could only write %zu instead of %zu bytes", r, len); +} + +static void read_and_wipe(int fd) { + ssize_t r; + off_t endpos, pos; + char *buf = malloc(BUFSIZE); + unsigned iteration = 0, rounds; + if (buf == NULL) + err(1, "malloc"); + + endpos = lseek(fd, 0, SEEK_END); + if (endpos == (off_t) -1) + err(1, "failed to seek end"); + if (endpos == 0) { + warnx("file is empty"); + return; + } + + pos = lseek(fd, 0, SEEK_SET); + if (pos == (off_t) -1) + err(1, "failed to seek to begin"); + + rounds = endpos / BUFSIZE; + if (rounds * BUFSIZE < endpos) + ++rounds; + + do { + r = read(fd, buf, BUFSIZE); + printf("\r%u/%u -- %u%% (%llu/%llu)", + iteration, rounds, + (unsigned) (100 * pos / endpos), + (long long) pos, (long long) endpos); + if (r < 0) { + warn("read failed"); + } else if (r > 0) { + char val = 0; + int i; + for (i = 0; i < r; i++) { + val |= buf[i]; + } + pos += r; + /* if there are any non-zero bytes, act accordingly */ + if (val != 0) { + printf(" WIPE ME!\n"); + wipe(fd, r); + } + } + fflush(stdout); + ++iteration; + } while (r > 0); + putchar('\n'); + + free(buf); +} + +int main(int argc, char **argv) { + int fd; + + if (argc < 2) + errx(1, "Missing device argument"); + + fd = open(argv[1], O_RDWR); + if (fd < 0) + err(1, "failed to open file"); + + read_and_wipe(fd); + + close(fd); + + return 0; +} -- cgit v1.2.1