Implement md5sum
This commit is contained in:
		
							parent
							
								
									a6d42ce5ca
								
							
						
					
					
						commit
						7d6c06b251
					
				@ -45,7 +45,7 @@ Utilities:
 | 
				
			|||||||
 * [ ] `logger`
 | 
					 * [ ] `logger`
 | 
				
			||||||
 * [ ] `logname`
 | 
					 * [ ] `logname`
 | 
				
			||||||
 * [ ] `ls`
 | 
					 * [ ] `ls`
 | 
				
			||||||
 * [ ] `md5sum`
 | 
					 * [x] `md5sum`
 | 
				
			||||||
 * [ ] `mkdir`
 | 
					 * [ ] `mkdir`
 | 
				
			||||||
 * [ ] `mkfifo`
 | 
					 * [ ] `mkfifo`
 | 
				
			||||||
 * [ ] `mktemp`
 | 
					 * [ ] `mktemp`
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										1
									
								
								go.sum
									
									
									
									
									
								
							@ -4,6 +4,7 @@ github.com/alexflint/go-scalar v1.0.0 h1:NGupf1XV/Xb04wXskDFzS0KWOLH632W/EO4fAFi
 | 
				
			|||||||
github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw=
 | 
					github.com/alexflint/go-scalar v1.0.0/go.mod h1:GpHzbCOZXEKMEcygYQ5n/aa4Aq84zbxjy3MxYW0gjYw=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 | 
					github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
 | 
					github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 | 
				
			||||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
					github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 | 
				
			||||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
					github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 | 
				
			||||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
					github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										199
									
								
								hashsum.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										199
									
								
								hashsum.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,199 @@
 | 
				
			|||||||
 | 
					package coreutils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bufio"
 | 
				
			||||||
 | 
						"crypto/md5"
 | 
				
			||||||
 | 
						"errors"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"hash"
 | 
				
			||||||
 | 
						"io"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"regexp"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/alexflint/go-arg"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var MD5Regex = regexp.MustCompile("^(?P<hash>[0-9a-f]{32})  (?P<filename>.*)$")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CheckingResults struct {
 | 
				
			||||||
 | 
						ImproperlyFormattedCount uint
 | 
				
			||||||
 | 
						InvalidChecksumCount     uint
 | 
				
			||||||
 | 
						FilesNotRead             uint
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SumFunc is a type of function that computes a hash.Hash for data in io.Reader
 | 
				
			||||||
 | 
					type SumFunc func(io.Reader) (hash.Hash, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// ImproperlyFormattedErr is an error return when a line for checking
 | 
				
			||||||
 | 
					// has an incorrect number or set of characters
 | 
				
			||||||
 | 
					var ImproperlyFormattedErr = errors.New("improperly formatted line")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func printHash(h hash.Hash, filename string) {
 | 
				
			||||||
 | 
						fmt.Printf("%x  %v\n", h.Sum(nil), filename)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PrintSumForFile prints checksum computed by f for file with filename
 | 
				
			||||||
 | 
					func PrintSumForFile(filename string, f SumFunc) error {
 | 
				
			||||||
 | 
						file, err := os.Open(filename)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer file.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h, err := f(file)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						printHash(h, filename)
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PrintSumForStdin prints checksum computed by f for data from stdin
 | 
				
			||||||
 | 
					func PrintSumForStdin(f SumFunc) {
 | 
				
			||||||
 | 
						h, err := f(os.Stdin)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							PrintToStderr(err)
 | 
				
			||||||
 | 
							os.Exit(1)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						printHash(h, "<stdin>")
 | 
				
			||||||
 | 
						os.Exit(0)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func checkLine(line string, re *regexp.Regexp, f SumFunc) (valid bool, err error) {
 | 
				
			||||||
 | 
						matches := re.MatchString(line)
 | 
				
			||||||
 | 
						if !matches {
 | 
				
			||||||
 | 
							err = ImproperlyFormattedErr
 | 
				
			||||||
 | 
							valid = false
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						submatches := re.FindStringSubmatch(line)
 | 
				
			||||||
 | 
						hash := submatches[1]
 | 
				
			||||||
 | 
						filename := submatches[2]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						file, err := os.Open(filename)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							valid = false
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer file.Close()
 | 
				
			||||||
 | 
						h, err := f(file)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							valid = false
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						result := "OK"
 | 
				
			||||||
 | 
						valid = true
 | 
				
			||||||
 | 
						if fmt.Sprintf("%x", h.Sum(nil)) != hash {
 | 
				
			||||||
 | 
							result = "FAILED"
 | 
				
			||||||
 | 
							valid = false
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Printf("%s: %s\n", filename, result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CheckSumsInReader checks checksums in r using f
 | 
				
			||||||
 | 
					func CheckSumsInReader(r io.Reader, re *regexp.Regexp, f SumFunc) (*CheckingResults, error) {
 | 
				
			||||||
 | 
						scanner := bufio.NewScanner(r)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						results := CheckingResults{}
 | 
				
			||||||
 | 
						for scanner.Scan() {
 | 
				
			||||||
 | 
							valid, err := checkLine(scanner.Text(), re, f)
 | 
				
			||||||
 | 
							if err == ImproperlyFormattedErr {
 | 
				
			||||||
 | 
								results.ImproperlyFormattedCount++
 | 
				
			||||||
 | 
							} else if err != nil {
 | 
				
			||||||
 | 
								PrintToStderr(err)
 | 
				
			||||||
 | 
								results.FilesNotRead++
 | 
				
			||||||
 | 
							} else if !valid {
 | 
				
			||||||
 | 
								results.InvalidChecksumCount++
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return &results, scanner.Err()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// CheckSumsInFile checks checksums in file with filename using f
 | 
				
			||||||
 | 
					func CheckSumsInFile(filename string, re *regexp.Regexp, f SumFunc) (*CheckingResults, error) {
 | 
				
			||||||
 | 
						file, err := os.Open(filename)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer file.Close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return CheckSumsInReader(file, re, f)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// PrintCheckingResults prints the number of mismatched checksums and improperly formatted lines to os.Stderr
 | 
				
			||||||
 | 
					func PrintCheckingResults(results CheckingResults) {
 | 
				
			||||||
 | 
						if results.InvalidChecksumCount > 0 {
 | 
				
			||||||
 | 
							PrintToStderr(
 | 
				
			||||||
 | 
								fmt.Sprintf("%v computed checksums did NOT match", results.InvalidChecksumCount),
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if results.ImproperlyFormattedCount > 0 {
 | 
				
			||||||
 | 
							PrintToStderr(
 | 
				
			||||||
 | 
								fmt.Sprintf("%v lines are improperly formatted", results.ImproperlyFormattedCount),
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if results.FilesNotRead > 0 {
 | 
				
			||||||
 | 
							PrintToStderr(
 | 
				
			||||||
 | 
								fmt.Sprintf("%v listed files could not be read", results.FilesNotRead),
 | 
				
			||||||
 | 
							)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// SumMain is a function you're supposed to run in main of a hash sum utility
 | 
				
			||||||
 | 
					func SumMain(re *regexp.Regexp, f SumFunc) {
 | 
				
			||||||
 | 
						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(f)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								results, err := CheckSumsInReader(os.Stdin, re, f)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									PrintToStderr(err)
 | 
				
			||||||
 | 
									exitCode = 1
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								PrintCheckingResults(*results)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						totalResults := CheckingResults{}
 | 
				
			||||||
 | 
						for _, filename := range args.Files {
 | 
				
			||||||
 | 
							if !args.Check {
 | 
				
			||||||
 | 
								err := PrintSumForFile(filename, f)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									PrintToStderr(err)
 | 
				
			||||||
 | 
									exitCode = 1
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								results, err := CheckSumsInFile(filename, re, f)
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									PrintToStderr(err)
 | 
				
			||||||
 | 
									exitCode = 1
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if results != nil {
 | 
				
			||||||
 | 
									totalResults.ImproperlyFormattedCount += results.ImproperlyFormattedCount
 | 
				
			||||||
 | 
									totalResults.InvalidChecksumCount += results.InvalidChecksumCount
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						PrintCheckingResults(totalResults)
 | 
				
			||||||
 | 
						os.Exit(exitCode)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										69
									
								
								hashsum_test.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								hashsum_test.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,69 @@
 | 
				
			|||||||
 | 
					package coreutils
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"bytes"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/suite"
 | 
				
			||||||
 | 
						"path"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
						"testing"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CheckLineTestSuite struct {
 | 
				
			||||||
 | 
						suite.Suite
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *CheckLineTestSuite) TestImproperlyFormattedLine() {
 | 
				
			||||||
 | 
						t := suite.T()
 | 
				
			||||||
 | 
						valid, err := checkLine("name chef", MD5Regex, MD5Sum)
 | 
				
			||||||
 | 
						assert.Equal(t, false, valid)
 | 
				
			||||||
 | 
						assert.Error(t, err)
 | 
				
			||||||
 | 
						assert.Equal(t, ImproperlyFormattedErr, err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *CheckLineTestSuite) TestMismatchedChecksum() {
 | 
				
			||||||
 | 
						t := suite.T()
 | 
				
			||||||
 | 
						line := "4a5fb9ebd6c8ea7efb53d071053ef778  " + path.Join("test_data", "some_file.txt")
 | 
				
			||||||
 | 
						valid, err := checkLine(line, MD5Regex, MD5Sum)
 | 
				
			||||||
 | 
						assert.Equal(t, false, valid)
 | 
				
			||||||
 | 
						assert.NoError(t, err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *CheckLineTestSuite) TestValid() {
 | 
				
			||||||
 | 
						t := suite.T()
 | 
				
			||||||
 | 
						line := "6a5fb9ebd6c8ea7efb53d071053ef778  " + path.Join("test_data", "some_file.txt")
 | 
				
			||||||
 | 
						valid, err := checkLine(line, MD5Regex, MD5Sum)
 | 
				
			||||||
 | 
						assert.Equal(t, true, valid)
 | 
				
			||||||
 | 
						assert.NoError(t, err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestCheckLineTestSuite(t *testing.T) {
 | 
				
			||||||
 | 
						suite.Run(t, new(CheckLineTestSuite))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type CheckSumsInReaderTestSuite struct {
 | 
				
			||||||
 | 
						suite.Suite
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (suite *CheckSumsInReaderTestSuite) Test() {
 | 
				
			||||||
 | 
						t := suite.T()
 | 
				
			||||||
 | 
						buf := bytes.NewBufferString(strings.Join(
 | 
				
			||||||
 | 
							[]string{
 | 
				
			||||||
 | 
								"name chef",
 | 
				
			||||||
 | 
								"4a5fb9ebd6c8ea7efb53d071053ef778  " + path.Join("test_data", "some_file.txt"),
 | 
				
			||||||
 | 
								"6a5fb9ebd6c8ea7efb53d071053ef778  " + path.Join("test_data", "some_file.txt"),
 | 
				
			||||||
 | 
								"4a5fb9ebd6c8ea7efb53d071053ef778  nonexistant_file",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							"\n",
 | 
				
			||||||
 | 
						))
 | 
				
			||||||
 | 
						results, err := CheckSumsInReader(buf, MD5Regex, MD5Sum)
 | 
				
			||||||
 | 
						assert.NotNil(t, results)
 | 
				
			||||||
 | 
						assert.Equal(t, uint(1), results.ImproperlyFormattedCount)
 | 
				
			||||||
 | 
						assert.Equal(t, uint(1), results.FilesNotRead)
 | 
				
			||||||
 | 
						assert.Equal(t, uint(1), results.InvalidChecksumCount)
 | 
				
			||||||
 | 
						assert.NoError(t, err)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestCheckSumsInReaderTestSuite(t *testing.T) {
 | 
				
			||||||
 | 
						suite.Run(t, new(CheckSumsInReaderTestSuite))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										134
									
								
								md5sum/md5sum.go
									
									
									
									
									
								
							
							
						
						
									
										134
									
								
								md5sum/md5sum.go
									
									
									
									
									
								
							@ -1,141 +1,9 @@
 | 
				
			|||||||
package main
 | 
					package main
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bufio"
 | 
					 | 
				
			||||||
	"crypto/md5"
 | 
					 | 
				
			||||||
	"errors"
 | 
					 | 
				
			||||||
	"fmt"
 | 
					 | 
				
			||||||
	"hash"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"strings"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/alexflint/go-arg"
 | 
					 | 
				
			||||||
	common "source.heropunch.io/tomo/go-coreutils"
 | 
						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() {
 | 
					func main() {
 | 
				
			||||||
	var args struct {
 | 
						common.SumMain(common.MD5Regex, common.MD5Sum)
 | 
				
			||||||
		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)
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										1
									
								
								test_data/some_file.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								test_data/some_file.txt
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					blah blah
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user