diskutil/wipe.go
2021-12-31 01:32:24 -05:00

113 lines
3.0 KiB
Go

package main
/*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
* <mitch@nerdfortress.dev> wrote this file. As long as you retain this notice you
* can do whatever you want with this stuff. If we meet some day, and you think
* this stuff is worth it, you can buy me a beer in return
* ----------------------------------------------------------------------------
*/
import (
"crypto/rand"
"fmt"
"io"
"os"
"time"
)
/**
wipe calls writeToDisk with correct arguments for dod wipe or wipe with zeros
@param wipeDod bool -- boolean for enable/disable random data over-write
@param blocksize int -- block size for each write iteration
@param wipeDisk string -- volume to wipe
*/
func wipe(wipeDod bool, blocksize int, wipeDisk string) {
if wipeDod {
for i := 0; i < 5; i++ {
fmt.Println("Starting wipe number", i+1, "at", time.Now())
writeToDisk(wipeDisk, blocksize, "random")
fmt.Println("Writing ones to disk at", time.Now())
writeToDisk(wipeDisk, blocksize, "one")
}
}
fmt.Println("Writing zeros to disk at", time.Now())
writeToDisk(wipeDisk, blocksize, "zero")
}
/**
writeToDisk opens a reader / writer file handler then iterates through the reader blocks and writes them as it does
@param wipeDisk string is the string of the volume/file to wipe
@param blocksize int is the int of the block size
@param writetype string expects "one", or "zero" other values will return randomByte()
*/
func writeToDisk(wipeDisk string, blocksize int, writeType string) {
zero := buildZero(blocksize)
p := make([]byte, blocksize)
fTarget, err := os.OpenFile(wipeDisk, os.O_WRONLY, 0644)
defer fTarget.Close()
errorHandler(err)
fRead, err := os.Open(wipeDisk)
defer fRead.Close()
i := 0
for {
var block []byte
i++
n, err := fRead.Read(p)
if err == io.EOF {
_, err := fTarget.Write(zero[:n])
errorHandler(err)
break
}
errorHandler(err)
if writeType == "zero" {
block = buildZero(blocksize)
} else if writeType == "one" {
block = buildOne(blocksize)
} else {
block = randomByte(blocksize)
}
_, err = fTarget.Write(block[:n])
}
fTarget.Sync()
}
/**
randomByte creates a []byte with random data
@param blocksize int -- size of the block to build
returns []byte containing random data
*/
func randomByte(blocksize int) []byte {
block := make([]byte, blocksize)
_, err := rand.Read(block)
errorHandler(err)
return block
}
/**
buildZero creates []byte of 0
@param blocksize int -- size of the block to build
returns []byte of size blocksize containing {0..0}
*/
func buildZero(blocksize int) []byte {
block := make([]byte, blocksize)
for i := 0; i < blocksize; i++ {
block[i] = 0
}
return block
}
/**
buildOne creates []byte of 1's
@param blocksize int -- size of block to build
returns []byte of size blocksize containing {0xff..0xff}
*/
func buildOne(blocksize int) []byte {
block := make([]byte, blocksize)
for i := 0; i < blocksize; i++ {
block[i] = 0xff
}
return block
}