-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
shred.go
115 lines (93 loc) · 2 KB
/
shred.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Package shred is a golang library to mimic the functionality of the linux shred command
package shred
import (
"crypto/rand"
"os"
"path/filepath"
)
// Conf is a object containing all choices of the user
type Conf struct {
Times int
Zeros bool
Remove bool
}
// Path shreds all files in the location of path
// recursively. If remove is set to true files will be deleted
// after shredding. When a file is shredded its content
// is NOT recoverable so USE WITH CAUTION!!!
func (conf Conf) Path(path string) error {
stats, err := os.Stat(path)
if err != nil {
return err
}
if stats.IsDir() {
return conf.Dir(path)
}
return conf.File(path)
}
// Dir overwrites every File in the location of path and everything in its subdirectories
func (conf Conf) Dir(path string) error {
var chErrors []chan error
walkFn := func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if info.IsDir() {
return nil
}
chErr := make(chan error)
chErrors = append(chErrors, chErr)
go func() {
err := conf.File(path)
chErr <- err
}()
return nil
}
if err := filepath.Walk(path, walkFn); err != nil {
return err
}
for _, chErr := range chErrors {
if err := <-chErr; err != nil {
return err
}
}
return nil
}
// File overwrites a given File in the location of path
func (conf Conf) File(path string) error {
for i := 0; i < conf.Times; i++ {
if err := overwriteFile(path, true); err != nil {
return err
}
}
if conf.Zeros {
if err := overwriteFile(path, false); err != nil {
return err
}
}
if conf.Remove {
if err := os.Remove(path); err != nil {
return err
}
}
return nil
}
func overwriteFile(path string, random bool) error {
f, err := os.OpenFile(path, os.O_WRONLY, 0)
if err != nil {
return err
}
defer f.Close()
info, err := f.Stat()
if err != nil {
return err
}
buff := make([]byte, info.Size())
if random {
if _, err := rand.Read(buff); err != nil {
return err
}
}
_, err = f.WriteAt(buff, 0)
return err
}