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