diff --git a/Makefile b/Makefile
deleted file mode 100644
index df4778b..0000000
--- a/Makefile
+++ /dev/null
@@ -1,89 +0,0 @@
-# Copyright © 2023 Thomas von Dein
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-
-#
-# no need to modify anything below
-tool = gowipe
-VERSION = $(shell grep VERSION main.go | head -1 | cut -d '"' -f2)
-archs = darwin freebsd linux windows
-PREFIX = /usr/local
-UID = root
-GID = 0
-HAVE_POD :=
-
-all: $(tool) buildlocal
-
-buildlocal:
- CGO_LDFLAGS='-static' go build -tags osusergo,netgo -ldflags "-extldflags=-static" -o $(tool)
-
-install: buildlocal
- install -d -o $(UID) -g $(GID) $(PREFIX)/bin
- install -d -o $(UID) -g $(GID) $(PREFIX)/man/man1
- install -o $(UID) -g $(GID) -m 555 $(tool) $(PREFIX)/sbin/
- install -o $(UID) -g $(GID) -m 444 $(tool).1 $(PREFIX)/man/man1/
-
-clean:
- rm -rf $(tool) coverage.out
-
-test:
- go test -v ./...
-
-singletest:
- @echo "Call like this: ''make singletest TEST=TestPrepareColumns"
- go test -run $(TEST)
-
-cover-report:
- go test ./... -cover -coverprofile=coverage.out
- go tool cover -html=coverage.out
-
-goupdate:
- go get -t -u=patch ./...
-
-buildall:
- ./mkrel.sh $(tool) $(VERSION)
-
-release:
- gh release create v$(VERSION) --generate-notes
-
-show-versions: buildlocal
- @echo "### gowipe version:"
- @./gowipe -v
-
- @echo
- @echo "### go module versions:"
- @go list -m all
-
- @echo
- @echo "### go version used for building:"
- @grep -m 1 go go.mod
-
-
-dir:
- rm -rf a
- mkdir -p a/b/c
- date > a/filea
- date > a/b/fileb
- date > a/b/c/filec
-
-bench: all
- dd if=/dev/zero of=t/fileZ bs=1024 count=200000
- dd if=/dev/zero of=t/fileM bs=1024 count=200000
- dd if=/dev/zero of=t/fileS bs=1024 count=200000
- dd if=/dev/zero of=t/fileE bs=1024 count=200000
- /usr/bin/time -f "%S" ./gowipe -Z t/fileZ
- /usr/bin/time -f "%S" ./gowipe -M t/fileM
- /usr/bin/time -f "%S" ./gowipe -S t/fileS
- /usr/bin/time -f "%S" ./gowipe -E t/fileE
diff --git a/README.md b/README.md
index e3058de..b091cf8 100644
--- a/README.md
+++ b/README.md
@@ -1,10 +1,12 @@
-## gowipe - securely delete files and directories (not for SSD)
-
-[](https://github.com/tlinden/gowipe/actions)
[](https://github.com/tlinden/gowipe/blob/master/LICENSE)
[](https://goreportcard.com/report/github.com/tlinden/gowipe)
[](https://github.com/TLINDEN/gowipe/releases/latest)
+## gowipe - securely delete files and directories (not for SSD)
+
+> [!CAUTION]
+> This software is now being maintained on [Codeberg](https://codeberg.org/scip/gowipe/).
+
## Description
`gowipe` is a simple self contained tool to securely wipe files and
diff --git a/crypto.go b/crypto.go
deleted file mode 100644
index ea65d92..0000000
--- a/crypto.go
+++ /dev/null
@@ -1,200 +0,0 @@
-/*
-Copyright © 2022-2025 Thomas von Dein
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-package main
-
-import (
- "crypto/cipher"
- cryptorand "crypto/rand"
- "errors"
- "fmt"
- "io"
- "math/big"
- mathrand "math/rand"
- "os"
- "time"
- "unsafe"
-
- "golang.org/x/crypto/argon2"
- chapo "golang.org/x/crypto/chacha20poly1305"
-)
-
-const (
- SaltSize = 32 // in bytes
- NonceSize = 24 // in bytes. taken from aead.NonceSize()
- KeySize = uint32(32) // KeySize is 32 bytes (256 bits).
- KeyTime = uint32(5)
- KeyMemory = uint32(1024 * 64) // KeyMemory in KiB. here, 64 MiB.
- KeyThreads = uint8(4)
- chunkSize = 1024 * 32 // chunkSize in bytes. here, 32 KiB.
-
- letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890-"
-
- letterIdxBits = 6 // 6 bits to represent a letter index
- letterIdxMask = 1<= 0; {
- if remain == 0 {
- cache, remain = src.Int63(), letterIdxMax
- }
- if idx := int(cache & letterIdxMask); idx < len(letters) {
- b[i] = letters[idx]
- i--
- }
- cache >>= letterIdxBits
- remain--
- }
-
- return *(*string)(unsafe.Pointer(&b))
-}
-
-func GetRandomKey() ([]byte, error) {
- password, err := GenerateSecureRandomBytes(int(chapo.KeySize))
- if err != nil {
- return nil, err
- }
-
- salt, err := GenerateSecureRandomBytes(chapo.NonceSizeX)
- if err != nil {
- return nil, err
- }
-
- key := argon2.IDKey(password, salt, KeyTime, KeyMemory, KeyThreads, chapo.KeySize)
-
- return key, nil
-}
-
-func Encrypt(c *Conf, filename string) error {
- info, err := os.Stat(filename)
- if err != nil {
- return err
- }
-
- size := info.Size()
-
- outfile, err := os.OpenFile(filename, os.O_RDWR|os.O_CREATE, 0666)
- if err != nil {
- return err
- }
- defer outfile.Close()
-
- key, err := GetRandomKey()
- if err != nil {
- return err
- }
-
- aead, err := chapo.NewX(key)
- if err != nil {
- return err
- }
-
- for i := 0; i < c.count; i++ {
- for {
- if size < chunkSize {
- if err := EncryptChunk(aead, outfile, size); err != nil {
- return err
- }
-
- break
- }
-
- if err := EncryptChunk(aead, outfile, chunkSize); err != nil {
- return err
- }
-
- size = size - chunkSize
-
- if size <= 0 {
- break
- }
- }
- }
-
- return nil
-}
-
-func EncryptChunk(aead cipher.AEAD, file *os.File, size int64) error {
- chunk := make([]byte, size)
- nonce, err := GenerateSecureRandomBytes(int(chapo.NonceSizeX))
- if err != nil {
- return err
- }
-
- cipher := aead.Seal(nil, nonce, chunk, nil)
-
- n, err := file.Write(cipher[:size])
- if err != nil {
- return err
- }
-
- if int64(n) != size {
- return errors.New("invalid number of bytes written")
- }
-
- return nil
-}
diff --git a/go.mod b/go.mod
deleted file mode 100644
index 2ff63bc..0000000
--- a/go.mod
+++ /dev/null
@@ -1,14 +0,0 @@
-module gowipe
-
-go 1.20
-
-require (
- github.com/JojiiOfficial/shred v1.2.1
- github.com/spf13/pflag v1.0.5
- golang.org/x/crypto v0.15.0
-)
-
-require (
- github.com/lu4p/shred v0.0.0-20201211173428-0347b645d724 // indirect
- golang.org/x/sys v0.14.0 // indirect
-)
diff --git a/go.sum b/go.sum
deleted file mode 100644
index 049ed97..0000000
--- a/go.sum
+++ /dev/null
@@ -1,10 +0,0 @@
-github.com/JojiiOfficial/shred v1.2.1 h1:658CFVTqcAkYVg815vW+guYnyJTLOIoS15tMyPTYhNo=
-github.com/JojiiOfficial/shred v1.2.1/go.mod h1:/OAxd6eYOhrXb3KW+2wmDog2BiFlUld8oJEKa+xblxU=
-github.com/lu4p/shred v0.0.0-20201211173428-0347b645d724 h1:nLJRUakdvy2j7JsefrtAUqGRbfJUKKqRu/3BCRA9mIQ=
-github.com/lu4p/shred v0.0.0-20201211173428-0347b645d724/go.mod h1:6b1kEKx7IPBboPSTnoJZE5sbSDjcNkHHO3Hii8TU8XY=
-github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
-github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-golang.org/x/crypto v0.15.0 h1:frVn1TEaCEaZcn3Tmd7Y2b5KKPaZ+I32Q2OA3kYp5TA=
-golang.org/x/crypto v0.15.0/go.mod h1:4ChreQoLWfG3xLDer1WdlH5NdlQ3+mwnQq1YTKY+72g=
-golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
-golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
diff --git a/main.go b/main.go
deleted file mode 100644
index 54af476..0000000
--- a/main.go
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
-Copyright © 2022-2025 Thomas von Dein
-
-This program is free software: you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program. If not, see .
-*/
-package main
-
-import (
- "fmt"
- "log"
- "os"
- "path/filepath"
- "strings"
- "time"
-
- "github.com/JojiiOfficial/shred"
- flag "github.com/spf13/pflag"
-)
-
-const VERSION string = "0.0.4"
-const Usage string = `This is gowipe - destruct files in a non-recoverable way.
-
-Usage: gowipe [-rcvz] ...
-
-Options:
--r --recursive Delete recursively
--c --count Overwrite files times
--m --mode Use for overwriting (or use -E, -S, -M, -Z)
--n --nodelete Do not delete files after overwriting
--N --norename Do not rename the files
--v --verbose Verbose output
--V --version Show program version
--h --help Show usage
-
-Available modes:
-zero Overwrite with zeroes (-Z)
-math Overwrite with math random bytes (-M)
-secure Overwrite with secure random bytes (default) (-S)
-encrypt Overwrite with ChaCha2Poly1305 encryption (most secure) (-E)`
-
-type Conf struct {
- mode string
- count int
- recurse bool
- nodelete bool
- norename bool
- verbose bool
- files int
- dirs int
- size int64
-}
-
-func main() {
- showversion := false
- showhelp := false
- optzero := false
- optsecure := false
- optmath := false
- optencrypt := false
-
- c := Conf{
- verbose: false,
- mode: `secure`,
- count: 30,
- recurse: false,
- nodelete: false,
- norename: false,
- }
-
- flag.BoolVarP(&showversion, "version", "V", showversion, "show version")
- flag.BoolVarP(&showhelp, "help", "h", showversion, "show help")
- flag.BoolVarP(&c.verbose, "verbose", "v", c.verbose, "verbose")
-
- flag.StringVarP(&c.mode, "mode", "m", c.mode, "overwrite mode")
-
- flag.BoolVarP(&optzero, "zero", "Z", optzero, "zero mode")
- flag.BoolVarP(&optsecure, "secure", "S", optsecure, "secure mode")
- flag.BoolVarP(&optmath, "math", "M", optmath, "math mode")
- flag.BoolVarP(&optencrypt, "encrypt", "E", optmath, "encrypt mode")
-
- flag.BoolVarP(&c.recurse, "recursive", "r", c.recurse, "recursive")
- flag.BoolVarP(&c.nodelete, "nodelete", "n", c.nodelete, "don't delete")
- flag.BoolVarP(&c.norename, "norename", "N", c.norename, "don't rename")
- flag.IntVarP(&c.count, "count", "c", c.count, "overwrite count")
-
- flag.Parse()
-
- if showversion {
- fmt.Printf("This is gowipe version %s\n", VERSION)
- os.Exit(0)
- }
-
- if showhelp {
- fmt.Println(Usage)
- os.Exit(0)
- }
-
- if len(flag.Args()) == 0 {
- fmt.Println(Usage)
- os.Exit(0)
- }
-
- var option shred.WriteOptions
-
- if optzero {
- option = shred.WriteZeros
- }
- if optmath {
- option = shred.WriteRand
- }
- if optsecure {
- option = shred.WriteRandSecure
- }
- if optencrypt {
- c.mode = "encrypt"
- }
-
- switch c.mode {
- case `secure`:
- option = shred.WriteRandSecure
- case `math`:
- option = shred.WriteRand
- case `zero`:
- option = shred.WriteZeros
- case `encrypt`:
- optencrypt = true
- default:
- option = shred.WriteRandSecure
- }
-
- shredder := shred.Shredder{}
- shredconf := shred.NewShredderConf(&shredder, option, c.count, !c.nodelete)
-
- start := time.Now()
-
- for _, file := range flag.Args() {
- Wipe(file, &c, shredconf)
- }
-
- if c.verbose {
- fmt.Println()
- fmt.Printf(" Dirs wiped: %d\n", c.dirs)
- fmt.Printf(" Files wiped: %d\n", c.files)
- fmt.Printf("Bytes deleted: %d\n", c.size)
- fmt.Printf(" Time elapsed: %s\n", time.Since(start))
- fmt.Printf(" Overwritten: %d times\n", c.count)
- fmt.Printf(" Wipe mode: %s\n", c.mode)
- fmt.Printf(" Recurse dirs: %t\n", c.recurse)
- }
-}
-
-func Wipe(file string, c *Conf, wiper *shred.ShredderConf) {
- if info, err := os.Stat(file); err == nil {
- if info.IsDir() {
- if !c.recurse {
- fmt.Printf("-r not set, ignoring directory %s\n", file)
- return
- }
-
- files, err := os.ReadDir(file)
- if err != nil {
- log.Fatal(err)
- }
-
- for _, entry := range files {
- Wipe(filepath.Join(file, entry.Name()), c, wiper)
- }
-
- // delete dir
- if !c.nodelete {
- err = os.Remove(Rename(file, c))
- if err != nil {
- log.Fatal(err)
- }
-
- c.dirs++
- }
- } else {
- if c.mode == "encrypt" {
- if err := Encrypt(c, file); err != nil {
- log.Fatal(err)
- }
-
- // delete encrypted file
- if !c.nodelete {
- err = os.Remove(Rename(file, c))
- if err != nil {
- log.Fatal(err)
- }
- }
- } else {
- if err := wiper.ShredFile(Rename(file, c)); err != nil {
- log.Fatal(err)
- }
- }
-
- c.size += info.Size()
- }
-
- if c.verbose {
- fmt.Printf("Wiped %s (%d bytes)\n", file, info.Size())
- }
-
- c.files++
- } else {
- if os.IsNotExist(err) {
- fmt.Printf("No such file or directory: %s\n", file)
- } else {
- fmt.Println(err)
- }
-
- os.Exit(1)
- }
-}
-
-func Rename(file string, c *Conf) string {
- var newname string
- dir := filepath.Dir(file)
- base := filepath.Base(file)
- length := len(base)
-
- for i := 0; i < c.count; i++ {
- for {
- switch c.mode {
- case `secure`, `encrypt`:
- new, err := GenerateSecureRandomString(length)
- if err != nil {
- log.Fatal(err)
- }
- newname = new
- case `math`:
- newname = GenerateMathRandomString(length)
- case `zero`:
- newname = strings.Repeat("0", length)
- }
- if newname != base {
- break
- }
- }
-
- err := os.Rename(filepath.Join(dir, base), filepath.Join(dir, newname))
- if err != nil {
- log.Fatal(err)
- }
-
- base = newname
- }
-
- return filepath.Join(dir, newname)
-}
diff --git a/mkrel.sh b/mkrel.sh
deleted file mode 100755
index f0f3d2c..0000000
--- a/mkrel.sh
+++ /dev/null
@@ -1,65 +0,0 @@
-#!/bin/bash
-
-# Copyright © 2022-2025 Thomas von Dein
-
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see .
-
-
-# get list with: go tool dist list
-DIST="darwin/amd64
-freebsd/amd64
-linux/amd64
-netbsd/amd64
-openbsd/amd64
-windows/amd64"
-
-tool="$1"
-version="$2"
-
-if test -z "$version"; then
- echo "Usage: $0 "
- exit 1
-fi
-
-rm -rf releases
-mkdir -p releases
-
-
-for D in $DIST; do
- os=${D/\/*/}
- arch=${D/*\//}
- binfile="releases/${tool}-${os}-${arch}-${version}"
- tardir="${tool}-${os}-${arch}-${version}"
- tarfile="releases/${tool}-${os}-${arch}-${version}.tar.gz"
- set -x
- GOOS=${os} GOARCH=${arch} go build -o ${binfile} -ldflags "-X 'github.com/tlinden/tablizer/cfg.VERSION=${version}'"
- mkdir -p ${tardir}
- cp ${binfile} README.md LICENSE ${tardir}/
- echo 'tool = gowipe
-PREFIX = /usr/local
-UID = root
-GID = 0
-
-install:
- install -d -o $(UID) -g $(GID) $(PREFIX)/bin
- install -d -o $(UID) -g $(GID) $(PREFIX)/man/man1
- install -o $(UID) -g $(GID) -m 555 $(tool) $(PREFIX)/sbin/
- install -o $(UID) -g $(GID) -m 444 $(tool).1 $(PREFIX)/man/man1/' > ${tardir}/Makefile
- tar cpzf ${tarfile} ${tardir}
- sha256sum ${binfile} | cut -d' ' -f1 > ${binfile}.sha256
- sha256sum ${tarfile} | cut -d' ' -f1 > ${tarfile}.sha256
- rm -rf ${tardir}
- set +x
-done
-