1*cf5a6c84SAndroid Build Coastguard Worker /* shred.c - Overwrite a file to securely delete
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2014 Rob Landley <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * No standard
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Worker USE_SHRED(NEWTOY(shred, "<1zxus#<1n#<1o#<0f", TOYFLAG_USR|TOYFLAG_BIN))
8*cf5a6c84SAndroid Build Coastguard Worker
9*cf5a6c84SAndroid Build Coastguard Worker config SHRED
10*cf5a6c84SAndroid Build Coastguard Worker bool "shred"
11*cf5a6c84SAndroid Build Coastguard Worker default y
12*cf5a6c84SAndroid Build Coastguard Worker help
13*cf5a6c84SAndroid Build Coastguard Worker usage: shred [-fuxz] [-n COUNT] [-o OFFSET] [-s SIZE] FILE...
14*cf5a6c84SAndroid Build Coastguard Worker
15*cf5a6c84SAndroid Build Coastguard Worker Securely delete a file by overwriting its contents with random data.
16*cf5a6c84SAndroid Build Coastguard Worker
17*cf5a6c84SAndroid Build Coastguard Worker -f Force (chmod if necessary)
18*cf5a6c84SAndroid Build Coastguard Worker -n COUNT Random overwrite iterations (default 1)
19*cf5a6c84SAndroid Build Coastguard Worker -o OFFSET Start at OFFSET
20*cf5a6c84SAndroid Build Coastguard Worker -s SIZE Use SIZE instead of detecting file size
21*cf5a6c84SAndroid Build Coastguard Worker -u Unlink (actually delete file when done)
22*cf5a6c84SAndroid Build Coastguard Worker -x Use exact size (default without -s rounds up to next 4k)
23*cf5a6c84SAndroid Build Coastguard Worker -z Zero at end
24*cf5a6c84SAndroid Build Coastguard Worker
25*cf5a6c84SAndroid Build Coastguard Worker Note: data journaling filesystems render this command useless, you must
26*cf5a6c84SAndroid Build Coastguard Worker overwrite all free space (fill up disk) to erase old data on those.
27*cf5a6c84SAndroid Build Coastguard Worker */
28*cf5a6c84SAndroid Build Coastguard Worker
29*cf5a6c84SAndroid Build Coastguard Worker #define FOR_shred
30*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
31*cf5a6c84SAndroid Build Coastguard Worker
GLOBALS(long o,n,s;)32*cf5a6c84SAndroid Build Coastguard Worker GLOBALS(
33*cf5a6c84SAndroid Build Coastguard Worker long o, n, s;
34*cf5a6c84SAndroid Build Coastguard Worker )
35*cf5a6c84SAndroid Build Coastguard Worker
36*cf5a6c84SAndroid Build Coastguard Worker void shred_main(void)
37*cf5a6c84SAndroid Build Coastguard Worker {
38*cf5a6c84SAndroid Build Coastguard Worker char **try;
39*cf5a6c84SAndroid Build Coastguard Worker
40*cf5a6c84SAndroid Build Coastguard Worker if (!FLAG(n)) TT.n++;
41*cf5a6c84SAndroid Build Coastguard Worker
42*cf5a6c84SAndroid Build Coastguard Worker // We don't use loopfiles() here because "-" isn't stdin, and want to
43*cf5a6c84SAndroid Build Coastguard Worker // respond to files we can't open via chmod.
44*cf5a6c84SAndroid Build Coastguard Worker
45*cf5a6c84SAndroid Build Coastguard Worker for (try = toys.optargs; *try; try++) {
46*cf5a6c84SAndroid Build Coastguard Worker off_t pos = 0, len = TT.s;
47*cf5a6c84SAndroid Build Coastguard Worker int fd = open(*try, O_RDWR), iter = 0, throw;
48*cf5a6c84SAndroid Build Coastguard Worker
49*cf5a6c84SAndroid Build Coastguard Worker // do -f chmod if necessary
50*cf5a6c84SAndroid Build Coastguard Worker if (fd == -1 && FLAG(f)) {
51*cf5a6c84SAndroid Build Coastguard Worker chmod(*try, 0600);
52*cf5a6c84SAndroid Build Coastguard Worker fd = open(*try, O_RDWR);
53*cf5a6c84SAndroid Build Coastguard Worker }
54*cf5a6c84SAndroid Build Coastguard Worker if (fd == -1) {
55*cf5a6c84SAndroid Build Coastguard Worker perror_msg_raw(*try);
56*cf5a6c84SAndroid Build Coastguard Worker continue;
57*cf5a6c84SAndroid Build Coastguard Worker }
58*cf5a6c84SAndroid Build Coastguard Worker
59*cf5a6c84SAndroid Build Coastguard Worker // determine length
60*cf5a6c84SAndroid Build Coastguard Worker if (!len) len = fdlength(fd);
61*cf5a6c84SAndroid Build Coastguard Worker if (len<1) {
62*cf5a6c84SAndroid Build Coastguard Worker error_msg("%s: needs -s", *try);
63*cf5a6c84SAndroid Build Coastguard Worker close(fd);
64*cf5a6c84SAndroid Build Coastguard Worker continue;
65*cf5a6c84SAndroid Build Coastguard Worker }
66*cf5a6c84SAndroid Build Coastguard Worker
67*cf5a6c84SAndroid Build Coastguard Worker // Loop through, writing to this file
68*cf5a6c84SAndroid Build Coastguard Worker for (;;) {
69*cf5a6c84SAndroid Build Coastguard Worker // Advance to next -n or -z?
70*cf5a6c84SAndroid Build Coastguard Worker
71*cf5a6c84SAndroid Build Coastguard Worker if (pos >= len) {
72*cf5a6c84SAndroid Build Coastguard Worker pos = -1;
73*cf5a6c84SAndroid Build Coastguard Worker if (++iter == TT.n && FLAG(z)) {
74*cf5a6c84SAndroid Build Coastguard Worker memset(toybuf, 0, sizeof(toybuf));
75*cf5a6c84SAndroid Build Coastguard Worker continue;
76*cf5a6c84SAndroid Build Coastguard Worker }
77*cf5a6c84SAndroid Build Coastguard Worker if (iter >= TT.n) break;
78*cf5a6c84SAndroid Build Coastguard Worker }
79*cf5a6c84SAndroid Build Coastguard Worker
80*cf5a6c84SAndroid Build Coastguard Worker if (pos < TT.o) {
81*cf5a6c84SAndroid Build Coastguard Worker if (TT.o != lseek(fd, TT.o, SEEK_SET)) {
82*cf5a6c84SAndroid Build Coastguard Worker perror_msg_raw(*try);
83*cf5a6c84SAndroid Build Coastguard Worker break;
84*cf5a6c84SAndroid Build Coastguard Worker }
85*cf5a6c84SAndroid Build Coastguard Worker pos = TT.o;
86*cf5a6c84SAndroid Build Coastguard Worker }
87*cf5a6c84SAndroid Build Coastguard Worker
88*cf5a6c84SAndroid Build Coastguard Worker // Determine length, read random data if not zeroing, write.
89*cf5a6c84SAndroid Build Coastguard Worker
90*cf5a6c84SAndroid Build Coastguard Worker throw = sizeof(toybuf);
91*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(x) && len-pos < throw) throw = len-pos;
92*cf5a6c84SAndroid Build Coastguard Worker
93*cf5a6c84SAndroid Build Coastguard Worker if (iter != TT.n) xgetrandom(toybuf, throw);
94*cf5a6c84SAndroid Build Coastguard Worker if (throw != writeall(fd, toybuf, throw)) perror_msg_raw(*try);
95*cf5a6c84SAndroid Build Coastguard Worker pos += throw;
96*cf5a6c84SAndroid Build Coastguard Worker }
97*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(u) && unlink(*try)) perror_msg("unlink '%s'", *try);
98*cf5a6c84SAndroid Build Coastguard Worker }
99*cf5a6c84SAndroid Build Coastguard Worker }
100