parent
b8b468f0b8
commit
a6d42ce5ca
2 changed files with 146 additions and 1 deletions
@ -0,0 +1,141 @@ |
|||||||
|
package main |
||||||
|
|
||||||
|
import ( |
||||||
|
"bufio" |
||||||
|
"crypto/md5" |
||||||
|
"errors" |
||||||
|
"fmt" |
||||||
|
"hash" |
||||||
|
"io" |
||||||
|
"os" |
||||||
|
"strings" |
||||||
|
|
||||||
|
"github.com/alexflint/go-arg" |
||||||
|
common "source.heropunch.io/tomo/go-coreutils" |
||||||
|
) |
||||||
|
|
||||||
|
var ImproperlyFormattedErr = errors.New("improperly formatted line") |
||||||
|
|
||||||
|
func printSumForFile(filename string, sumFunc func(io.Reader) (hash.Hash, error)) error { |
||||||
|
file, err := os.Open(filename) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
defer file.Close() |
||||||
|
|
||||||
|
h, err := sumFunc(file) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
|
||||||
|
printHash(h, filename) |
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func printSumForStdin(sumFunc func(io.Reader) (hash.Hash, error)) { |
||||||
|
h, err := sumFunc(os.Stdin) |
||||||
|
if err != nil { |
||||||
|
common.PrintToStderr(err) |
||||||
|
os.Exit(1) |
||||||
|
} |
||||||
|
printHash(h, "<stdin>") |
||||||
|
os.Exit(0) |
||||||
|
} |
||||||
|
|
||||||
|
func md5sum(r io.Reader) (hash.Hash, error) { |
||||||
|
h := md5.New() |
||||||
|
if _, err := io.Copy(h, r); err != nil { |
||||||
|
return nil, err |
||||||
|
} |
||||||
|
return h, nil |
||||||
|
} |
||||||
|
|
||||||
|
func printHash(h hash.Hash, filename string) { |
||||||
|
fmt.Printf("%x %v\n", h.Sum(nil), filename) |
||||||
|
} |
||||||
|
|
||||||
|
func checkSumForFile(filename string) error { |
||||||
|
file, err := os.Open(filename) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
defer file.Close() |
||||||
|
|
||||||
|
return checkSums(file) |
||||||
|
} |
||||||
|
|
||||||
|
func checkSums(r io.Reader) error { |
||||||
|
scanner := bufio.NewScanner(r) |
||||||
|
|
||||||
|
for scanner.Scan() { |
||||||
|
err := checkMD5Sum(scanner.Text()) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
} |
||||||
|
return scanner.Err() |
||||||
|
} |
||||||
|
|
||||||
|
func checkMD5Sum(line string) error { |
||||||
|
s := strings.SplitN(line, " ", 2) |
||||||
|
hash := s[0] |
||||||
|
filename := s[1] |
||||||
|
|
||||||
|
if filename == "" { |
||||||
|
return ImproperlyFormattedErr |
||||||
|
} |
||||||
|
|
||||||
|
file, err := os.Open(filename) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
defer file.Close() |
||||||
|
|
||||||
|
h, err := md5sum(file) |
||||||
|
if err != nil { |
||||||
|
return err |
||||||
|
} |
||||||
|
result := "OK" |
||||||
|
if fmt.Sprintf("%x", h.Sum(nil)) != hash { |
||||||
|
result = "FAILED" |
||||||
|
} |
||||||
|
fmt.Printf("%s: %s\n", filename, result) |
||||||
|
|
||||||
|
return nil |
||||||
|
} |
||||||
|
|
||||||
|
func main() { |
||||||
|
var args struct { |
||||||
|
Check bool `arg:"-c"` |
||||||
|
Files []string `arg:"positional"` |
||||||
|
} |
||||||
|
|
||||||
|
arg.MustParse(&args) |
||||||
|
|
||||||
|
exitCode := 0 |
||||||
|
if len(args.Files) == 0 { |
||||||
|
if !args.Check { |
||||||
|
printSumForStdin(md5sum) |
||||||
|
} else { |
||||||
|
fmt.Println("Checking from stdin") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for _, filename := range args.Files { |
||||||
|
if !args.Check { |
||||||
|
err := printSumForFile(filename, md5sum) |
||||||
|
if err != nil { |
||||||
|
common.PrintToStderr(err) |
||||||
|
exitCode = 1 |
||||||
|
} |
||||||
|
} else { |
||||||
|
err := checkSumForFile(filename) |
||||||
|
if err != nil { |
||||||
|
common.PrintToStderr(err) |
||||||
|
exitCode = 1 |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
os.Exit(exitCode) |
||||||
|
} |
Loading…
Reference in new issue