From: Mike Frysinger Date: Sat, 15 Aug 2020 07:20:11 +0000 (-0400) Subject: ddnuke: add fdisk+prompt to startup, and rough ETA X-Git-Url: https://git.wh0rd.org/?p=home.git;a=commitdiff_plain;h=942a43e2e16198361bee17df0077435a5064a2ed ddnuke: add fdisk+prompt to startup, and rough ETA --- diff --git a/ddnuke.c b/ddnuke.c index 1712d16..388a144 100644 --- a/ddnuke.c +++ b/ddnuke.c @@ -11,11 +11,13 @@ #define _LARGEFILE64_SOURCE #define _GNU_SOURCE +#include #include #include #include #include #include +#include #include #include #include @@ -25,6 +27,8 @@ #include #include #include +#include +#include #include static unsigned long long mbps(struct timespec *stime, struct timespec *etime, off_t len) @@ -41,7 +45,7 @@ static off_t get_blk_size(int fd) { uint64_t size; if (ioctl(fd, BLKGETSIZE64, &size)) - err(1, "ioctl(BLKGETSIZE64) failed"); + err(EX_DATAERR, "ioctl(BLKGETSIZE64) failed"); return size; } @@ -50,7 +54,7 @@ static off_t get_size(int fd) struct stat st; if (fstat(fd, &st)) - err(1, "could not stat %i", fd); + err(EX_DATAERR, "could not stat %i", fd); if (S_ISREG(st.st_mode)) return st.st_size; @@ -58,7 +62,7 @@ static off_t get_size(int fd) return get_blk_size(fd); errno = EINVAL; - err(1, "unknown type of file"); + err(EX_DATAERR, "unknown type of file"); } static void nuke(int fd, off_t offset, off_t max_size, unsigned char pattern) @@ -69,7 +73,7 @@ static void nuke(int fd, off_t offset, off_t max_size, unsigned char pattern) printf("Writing 0x%X to the output\n", pattern); if (lseek(fd, offset, SEEK_SET) != offset) - err(1, "lseek(%"PRIu64"u) failed", offset); + err(EX_DATAERR, "lseek(%"PRIu64"u) failed", offset); unsigned long long speed = 0; struct timespec stime, etime, itime; @@ -90,8 +94,10 @@ static void nuke(int fd, off_t offset, off_t max_size, unsigned char pattern) return; } - printf("\r\e[2K%'llu bytes %u%% (%'llu MB/s)", (unsigned long long)pos, - (unsigned)((pos * 100) / max_size), speed); + unsigned long long eta = speed ? (max_size - pos) / (speed * 1000 * 1000) : 0; + printf("\r\e[2K%'llu bytes %u%% (%'llu MB/s) (ETA ~%llum%llus)", + (unsigned long long)pos, (unsigned)((pos * 100) / max_size), speed, + eta / 60, eta % 60); if ((++fsync_pos % 32) == 0) { speed = mbps(&stime, &etime, pos - last_pos); @@ -111,6 +117,8 @@ static void usage(int status) "Usage: ddnuke [options] \n" "\n" "Options:\n" + " -q Run quietly\n" + " -y Assume yes to all prompts\n" " -o Position to start writing\n" " -r Write three times: 0x00, then 0xaa, then 0x55\n" ); @@ -121,19 +129,27 @@ int main(int argc, char *argv[]) { off_t offset = 0; const char *file; + bool quiet = false; bool random = false; + bool yes = false; int o; setlocale(LC_NUMERIC, "en_US"); - while ((o = getopt(argc, argv, "ho:r")) != -1) { + while ((o = getopt(argc, argv, "ho:qry")) != -1) { switch (o) { case 'o': offset = atoll(optarg); break; + case 'q': + quiet = true; + break; case 'r': random = true; break; + case 'y': + yes = true; + break; case 'h': usage(EX_OK); break; @@ -148,7 +164,25 @@ int main(int argc, char *argv[]) int fd = open(file, O_WRONLY|O_CLOEXEC); if (fd == -1) - err(1, "open(%s) failed", file); + err(EX_NOINPUT, "open(%s) failed", file); + + if (!quiet) { + pid_t pid; + const char *argv[] = {"fdisk", "-l", file, NULL}; + if (posix_spawnp(&pid, argv[0], NULL, NULL, (char *const *)argv, NULL)) + err(EX_OSERR, "spawn(%s %s) failed", argv[0], file); + waitpid(pid, NULL, 0); + printf("\n"); + } + + if (!yes) { + printf("Do you want to wipe '%s'? (y/N) ", file); + fflush(stdout); + char c = 0; + if (fread(&c, 1, 1, stdin)) {/* don't care */} + if (tolower(c) != 'y') + errx(EX_UNAVAILABLE, "User decided not to wipe"); + } off_t max_size = get_size(fd);