]>
git.wh0rd.org - home.git/blob - ddnuke.c
2 * released into the public domain
3 * written by Mike Frysinger <vapier>
6 #pragma GCC diagnostic warning "-Wall"
7 #pragma GCC diagnostic warning "-Wextra"
9 #define _FILE_OFFSET_BITS 64
10 #define _LARGEFILE_SOURCE
11 #define _LARGEFILE64_SOURCE
26 #include <sys/ioctl.h>
30 static unsigned long long mbps(struct timespec
*stime
, struct timespec
*etime
, off_t len
)
33 clock_gettime(CLOCK_MONOTONIC
, etime
);
34 dtime
= ((etime
->tv_sec
- stime
->tv_sec
) * 1000 * 1000 * 1000) +
35 (etime
->tv_nsec
- stime
->tv_nsec
);
37 return 1000 * len
/ dtime
;
40 static off_t
get_blk_size(int fd
)
43 if (ioctl(fd
, BLKGETSIZE64
, &size
))
44 err(1, "ioctl(BLKGETSIZE64) failed");
48 static off_t
get_size(int fd
)
53 err(1, "could not stat %i", fd
);
55 if (S_ISREG(st
.st_mode
))
57 else if (S_ISBLK(st
.st_mode
))
58 return get_blk_size(fd
);
61 err(1, "unknown type of file");
64 static void nuke(int fd
, off_t offset
, off_t max_size
, unsigned char pattern
)
66 static char mem
[1024 * 1024];
67 memset(mem
, pattern
, sizeof(mem
));
69 printf("Writing 0x%X to the output\n", pattern
);
71 if (lseek(fd
, offset
, SEEK_SET
) != offset
)
72 err(1, "lseek(%"PRIu64
"u) failed", offset
);
74 unsigned long long speed
= 0;
75 struct timespec stime
, etime
, itime
;
76 clock_gettime(CLOCK_MONOTONIC
, &stime
);
79 off_t pos
= offset
, last_pos
= 0;
82 while (pos
< max_size
) {
83 /* This will round up to sizeof(mem) ... */
84 ret
= write(fd
, mem
, sizeof(mem
));
86 if (ret
!= sizeof(mem
)) {
88 printf("\nread() returned %zi (wanted %zu)\n%'llu MB/s over entire run\n",
89 ret
, sizeof(mem
), mbps(&itime
, &etime
, pos
));
93 printf("\r\e[2K%'llu bytes %u%% (%'llu MB/s)", (unsigned long long)pos
,
94 (unsigned)((pos
* 100) / max_size
), speed
);
96 if ((++fsync_pos
% 32) == 0) {
97 speed
= mbps(&stime
, &etime
, pos
- last_pos
);
107 static void usage(int status
)
110 status
? stderr
: stdout
,
111 "Usage: ddnuke [options] <dev>\n"
114 " -o <offset> Position to start writing\n"
115 " -r Write three times: 0x00, then 0xaa, then 0x55\n"
120 int main(int argc
, char *argv
[])
127 setlocale(LC_NUMERIC
, "en_US");
129 while ((o
= getopt(argc
, argv
, "ho:r")) != -1) {
132 offset
= atoll(optarg
);
145 if (argc
!= optind
+ 1)
149 int fd
= open(file
, O_WRONLY
|O_CLOEXEC
);
151 err(1, "open(%s) failed", file
);
153 off_t max_size
= get_size(fd
);
155 nuke(fd
, offset
, max_size
, 0x00);
157 nuke(fd
, offset
, max_size
, 0xaa);
158 nuke(fd
, offset
, max_size
, 0x55);