From a46936095d57e181b432db4be0632edbcf6ffff2 Mon Sep 17 00:00:00 2001 From: Zach Kipp Date: Sat, 25 Sep 2021 11:07:56 -0700 Subject: [PATCH] Remove the need to edit code for compilation when not on Windows --- src/Picocrypt.go | 159 +++------------------------------------------ src/README.md | 13 ++-- src/cmd_unix.go | 82 +++++++++++++++++++++++ src/cmd_windows.go | 79 ++++++++++++++++++++++ 4 files changed, 175 insertions(+), 158 deletions(-) create mode 100644 src/cmd_unix.go create mode 100644 src/cmd_windows.go diff --git a/src/Picocrypt.go b/src/Picocrypt.go index 5b6e34f..016ccbf 100644 --- a/src/Picocrypt.go +++ b/src/Picocrypt.go @@ -25,20 +25,16 @@ import ( "image/color" "image/png" "io" - "io/ioutil" "math" "math/big" "net/http" "os" - "os/exec" "path/filepath" "regexp" "runtime" "runtime/debug" "strconv" "strings" - "sync" - "syscall" "time" // Cryptography @@ -77,9 +73,6 @@ var icon []byte //go:embed font.ttf var font []byte -//go:embed sdelete64.exe -var sdelete64bytes []byte - //go:embed strings.json var localeBytes []byte @@ -107,7 +100,6 @@ var mode string var working bool var recombine bool var fill float32 = -0.0000001 -var sdelete64path string // Three variables store the input files var onlyFiles []string @@ -957,7 +949,9 @@ func onDrop(names []string) { return } if tab == 2 { - go shred(names, true) + namesCopy := make([]string, len(names)) + copy(namesCopy, names) + go doShred(namesCopy, true) return } @@ -1894,7 +1888,7 @@ func work() { if shredTemp { progressInfo = "" popupStatus = s("Shredding temporary files...") - shred([]string{inputFile + ".pcv"}, false) + doShred([]string{inputFile + ".pcv"}, false) } else { os.Remove(inputFile + ".pcv") } @@ -1911,7 +1905,7 @@ func work() { progressInfo = "" popupStatus = s("Shredding temporary files...") giu.Update() - shred([]string{inputFile}, false) + doShred([]string{inputFile}, false) } else { os.Remove(inputFile) } @@ -2080,7 +2074,7 @@ func generateChecksums(file string) { } // Recursively shred all file(s) and folder(s) passed in as 'names' -func shred(names []string, separate bool) { +func doShred(names []string, separate bool) { stopShredding = false shredTotal = 0 shredDone = 0 @@ -2106,133 +2100,7 @@ func shred(names []string, separate bool) { for _, name := range names { shredding = name - - // Linux and macOS need a command with similar syntax and usage, so they're combined - if runtime.GOOS == "linux" || runtime.GOOS == "darwin" { - stat, _ := os.Stat(name) - if stat.IsDir() { - var coming []string - - // Walk the folder recursively - filepath.Walk(name, func(path string, _ os.FileInfo, err error) error { - if err != nil { - return nil - } - if stopShredding { - return nil - } - stat, _ := os.Stat(path) - if !stat.IsDir() { - if len(coming) == 128 { - // Use a WaitGroup to parallelize shredding - var wg sync.WaitGroup - for i, j := range coming { - wg.Add(1) - go func(wg *sync.WaitGroup, id int, j string) { - defer wg.Done() - shredding = j - var cmd *exec.Cmd - if runtime.GOOS == "linux" { - cmd = exec.Command("shred", "-ufvz", "-n", strconv.Itoa(int(shredPasses)), j) - } else { - cmd = exec.Command("rm", "-rfP", j) - } - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - cmd.Run() - shredDone++ - shredUpdate(separate) - giu.Update() - }(&wg, i, j) - } - wg.Wait() - coming = nil - } else { - coming = append(coming, path) - } - } - return nil - }) - for _, i := range coming { - if stopShredding { - break - } - go func(i string) { - shredding = i - var cmd *exec.Cmd - if runtime.GOOS == "linux" { - cmd = exec.Command("shred", "-ufvz", "-n", strconv.Itoa(int(shredPasses)), i) - } else { - cmd = exec.Command("rm", "-rfP", i) - } - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - cmd.Run() - shredDone++ - shredUpdate(separate) - giu.Update() - }(i) - } - if !stopShredding { - os.RemoveAll(name) - } - } else { // The path is a file, not a directory, so just shred it - shredding = name - var cmd *exec.Cmd - if runtime.GOOS == "linux" { - cmd = exec.Command("shred", "-ufvz", "-n", strconv.Itoa(int(shredPasses)), name) - } else { - cmd = exec.Command("rm", "-rfP", name) - } - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - cmd.Run() - shredDone++ - shredUpdate(separate) - } - } else if runtime.GOOS == "windows" { - stat, _ := os.Stat(name) - if stat.IsDir() { - // Walk the folder recursively - filepath.Walk(name, func(path string, _ os.FileInfo, err error) error { - if err != nil { - return nil - } - stat, _ := os.Stat(path) - if stat.IsDir() { - if stopShredding { - return nil - } - - t := 0 - files, _ := ioutil.ReadDir(path) - for _, f := range files { - if !f.IsDir() { - t++ - } - } - shredDone += float32(t) - shredUpdate(separate) - shredding = strings.ReplaceAll(path, "\\", "/") + "/*" - cmd := exec.Command(sdelete64path, "*", "-p", strconv.Itoa(int(shredPasses))) - cmd.Dir = path - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - cmd.Run() - giu.Update() - } - return nil - }) - - if !stopShredding { - // sdelete64 doesn't delete the empty folder, so I'll do it manually - os.RemoveAll(name) - } - } else { - shredding = name - cmd := exec.Command(sdelete64path, name, "-p", strconv.Itoa(int(shredPasses))) - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - cmd.Run() - shredDone++ - shredUpdate(separate) - } - } + shred(1, false, name, &shredding) giu.Update() if stopShredding { return @@ -2421,14 +2289,8 @@ func main() { } } - // Create a temporary file to store sdelete64.exe - sdelete64, _ := os.CreateTemp("", "sdelete64.*.exe") - sdelete64path = sdelete64.Name() - sdelete64.Write(sdelete64bytes) - sdelete64.Close() - cmd := exec.Command(sdelete64path, "/accepteula") - cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} - cmd.Run() + cleanup := initializeShred() + defer cleanup() // Set a universal font giu.SetDefaultFontFromBytes(font, 18) @@ -2468,7 +2330,4 @@ func main() { // Start the UI window.Run(draw) - - // Window closed, clean up - os.Remove(sdelete64path) } diff --git a/src/README.md b/src/README.md index d98d759..b957947 100644 --- a/src/README.md +++ b/src/README.md @@ -18,14 +18,11 @@ If you don't have Go installed, download the corresponding installer for Go from # 3. Get the Source Files Download the source files as a zip from the homepage or `git clone` this repository. -# 4. If You're Not on Windows... -Windows requires a couple of extra lines to hide the command prompt window that shows when shredding a file. If you're not on Windows, however, you'll need to delete all occurrences of this line: `cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow:true}`. You'll also need to remove the import of `syscall`. - -# 5. Build From Source +# 4. Build From Source Finally, build Picocrypt from source: -- Windows: go build -ldflags "-s -w -H=windowsgui -extldflags=-static" Picocrypt.go -- macOS: go build -ldflags "-s -w" Picocrypt.go -- Linux: go build -ldflags "-s -w" Picocrypt.go +- Windows: go build -ldflags "-s -w -H=windowsgui -extldflags=-static" +- macOS: go build -ldflags "-s -w" +- Linux: go build -ldflags "-s -w" -# 6. Done! +# 5. Done! You should now see a compiled executable (`Picocrypt.exe`/`Picocrypt`) in your directory. You can run it by double-clicking or executing it in your terminal. That wasn't too hard, right? Enjoy! diff --git a/src/cmd_unix.go b/src/cmd_unix.go new file mode 100644 index 0000000..2d97af5 --- /dev/null +++ b/src/cmd_unix.go @@ -0,0 +1,82 @@ +// +build linux darwin + +package main + +import ( + "os" + "os/exec" + "path/filepath" + "runtime" + "strconv" + "sync" + + "github.com/AllenDang/giu" +) + +func shred(passes int, separate bool, name string, shredding *string) { + stat, _ := os.Stat(name) + if stat.IsDir() { + var coming []string + + // Walk the folder recursively + filepath.Walk(name, func(path string, _ os.FileInfo, err error) error { + if err != nil { + return nil + } + if stopShredding { + return nil + } + stat, _ := os.Stat(path) + if !stat.IsDir() { + if len(coming) == 128 { + // Use a WaitGroup to parallelize shredding + var wg sync.WaitGroup + for i, j := range coming { + wg.Add(1) + go func(wg *sync.WaitGroup, id int, j string) { + defer wg.Done() + runShredCommand(j, separate) + giu.Update() + }(&wg, i, j) + } + wg.Wait() + coming = nil + } else { + coming = append(coming, path) + } + } + return nil + }) + for _, i := range coming { + if stopShredding { + break + } + go func(i string) { + runShredCommand(i, separate) + giu.Update() + }(i) + } + if !stopShredding { + os.RemoveAll(name) + } + } else { // The path is a file, not a directory, so just shred it + runShredCommand(name, separate) + } +} + +func runShredCommand(name string, separate bool) { + shredding = name + var cmd *exec.Cmd + if runtime.GOOS == "linux" { + cmd = exec.Command("shred", "-ufvz", "-n", strconv.Itoa(int(shredPasses)), name) + } else { + cmd = exec.Command("rm", "-rfP", name) + } + cmd.Run() + shredDone++ + shredUpdate(separate) +} + +func initializeShred() func() { + return func() {} +} diff --git a/src/cmd_windows.go b/src/cmd_windows.go new file mode 100644 index 0000000..ada18d4 --- /dev/null +++ b/src/cmd_windows.go @@ -0,0 +1,79 @@ +// +build windows + +package main + +import ( + "io/ioutil" + "os" + "os/exec" + "path/filepath" + "strconv" + "strings" + "syscall" + + "github.com/AllenDang/giu" +) + +//go:embed sdelete64.exe +var sdelete64bytes []byte + +var sdelete64path string + +func shred(passes int, separate bool, name string, shredding *string) { + stat, _ := os.Stat(name) + if stat.IsDir() { + // Walk the folder recursively + filepath.Walk(name, func(path string, _ os.FileInfo, err error) error { + if err != nil { + return nil + } + stat, _ := os.Stat(path) + if stat.IsDir() { + if stopShredding { + return nil + } + + t := 0 + files, _ := ioutil.ReadDir(path) + for _, f := range files { + if !f.IsDir() { + t++ + } + } + shredDone += float32(t) + shredUpdate(separate) + shredding = strings.ReplaceAll(path, "\\", "/") + "/*" + cmd := exec.Command(sdelete64path, "*", "-p", strconv.Itoa(passes)) + cmd.Dir = path + cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} + cmd.Run() + giu.Update() + } + return nil + }) + + if !stopShredding { + // sdelete64 doesn't delete the empty folder, so I'll do it manually + os.RemoveAll(name) + } + } else { + shredding = name + cmd := exec.Command(sdelete64path, "*", "-p", strconv.Itoa(passes)) + cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} + cmd.Run() + shredDone++ + shredUpdate(separate) + } +} + +func initializeShred() func() { + // Create a temporary file to store sdelete64.exe + sdelete64, _ := os.CreateTemp("", "sdelete64.*.exe") + sdelete64path = sdelete64.Name() + sdelete64.Write(sdelete64bytes) + sdelete64.Close() + cmd := exec.Command(s64deletepath, "/accepteula") + cmd.SysProcAttr = &syscall.SysProcAttr{HideWindow: true} + cmd.Run() + return func() { os.Remove(sdelete64path) } +}