Add zsearch and dumpbytes.
This commit is contained in:
parent
f6d227946b
commit
9715293773
|
@ -0,0 +1,71 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"git.wntrmute.dev/kyle/goutils/die"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func usage(w io.Writer, exc int) {
|
||||||
|
fmt.Fprintln(w, `usage: dumpbytes <file>`)
|
||||||
|
os.Exit(exc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func printBytes(buf []byte) {
|
||||||
|
fmt.Printf("\t")
|
||||||
|
for i := 0; i < len(buf); i++ {
|
||||||
|
fmt.Printf("0x%02x, ", buf[i])
|
||||||
|
}
|
||||||
|
fmt.Println()
|
||||||
|
}
|
||||||
|
|
||||||
|
func dumpFile(path string, indentLevel int) error {
|
||||||
|
indent := ""
|
||||||
|
for i := 0; i < indentLevel; i++ {
|
||||||
|
indent += "\t"
|
||||||
|
}
|
||||||
|
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
fmt.Printf("%svar buffer = []byte{\n", indent)
|
||||||
|
for {
|
||||||
|
buf := make([]byte, 8)
|
||||||
|
n, err := file.Read(buf)
|
||||||
|
if err == io.EOF {
|
||||||
|
if n > 0 {
|
||||||
|
fmt.Printf("%s", indent)
|
||||||
|
printBytes(buf[:n])
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s", indent)
|
||||||
|
printBytes(buf[:n])
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s}\n", indent)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
indent := 0
|
||||||
|
flag.Usage = func() { usage(os.Stderr, 0) }
|
||||||
|
flag.IntVar(&indent, "n", 0, "indent level")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
for _, file := range flag.Args() {
|
||||||
|
err := dumpFile(file, indent)
|
||||||
|
die.If(err)
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,136 @@
|
||||||
|
// zsearch is a utility for searching zlib-compressed files for a
|
||||||
|
// search string. It was really designed for use with the Git object
|
||||||
|
// store, i.e. to aid in the recovery of files after Git does what Git
|
||||||
|
// do.
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"bytes"
|
||||||
|
"compress/zlib"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"regexp"
|
||||||
|
)
|
||||||
|
|
||||||
|
const defaultDirectory = ".git/objects"
|
||||||
|
|
||||||
|
func errorf(format string, a ...interface{}) {
|
||||||
|
fmt.Fprintf(os.Stderr, format, a...)
|
||||||
|
if format[len(format)-1] != '\n' {
|
||||||
|
fmt.Fprintf(os.Stderr, "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func isDir(path string) bool {
|
||||||
|
fi, err := os.Stat(path)
|
||||||
|
if err != nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return fi.IsDir()
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadFile(path string) ([]byte, error) {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
zread, err := zlib.NewReader(file)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer zread.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(buf, zread)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return buf.Bytes(), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func showFile(path string) {
|
||||||
|
fileData, err := loadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
errorf("%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%s\n", fileData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func searchFile(path string, search *regexp.Regexp) error {
|
||||||
|
file, err := os.Open(path)
|
||||||
|
if err != nil {
|
||||||
|
errorf("%v")
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
zread, err := zlib.NewReader(file)
|
||||||
|
if err != nil {
|
||||||
|
errorf("%v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer zread.Close()
|
||||||
|
|
||||||
|
zbuf := bufio.NewReader(zread)
|
||||||
|
if search.MatchReader(zbuf) {
|
||||||
|
fileData, err := loadFile(path)
|
||||||
|
if err != nil {
|
||||||
|
errorf("%v", err)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Printf("%s:\n%s\n", path, fileData)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildWalker(searchExpr *regexp.Regexp) filepath.WalkFunc {
|
||||||
|
return func(path string, info os.FileInfo, err error) error {
|
||||||
|
if info.Mode().IsRegular() {
|
||||||
|
return searchFile(path, searchExpr)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flSearch := flag.String("s", "", "search string (should be an RE2 regular expression)")
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *flSearch == "" {
|
||||||
|
for _, path := range flag.Args() {
|
||||||
|
showFile(path)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
search, err := regexp.Compile(*flSearch)
|
||||||
|
if err != nil {
|
||||||
|
errorf("Bad regexp: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
pathList := flag.Args()
|
||||||
|
if len(pathList) == 0 {
|
||||||
|
pathList = []string{defaultDirectory}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, path := range pathList {
|
||||||
|
if isDir(path) {
|
||||||
|
err := filepath.Walk(path, buildWalker(search))
|
||||||
|
if err != nil {
|
||||||
|
errorf("%v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
searchFile(path, search)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue