diff options
Diffstat (limited to 'internal/slackware_com/checksums.go')
-rw-r--r-- | internal/slackware_com/checksums.go | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/internal/slackware_com/checksums.go b/internal/slackware_com/checksums.go new file mode 100644 index 0000000..643e204 --- /dev/null +++ b/internal/slackware_com/checksums.go @@ -0,0 +1,143 @@ +package slackware_com + +import ( + "bufio" + "bytes" + "crypto/md5" + "errors" + "fmt" + "hash" + "io" + "os" + "path" + "strings" +) + +var checksumsHeader = strings.TrimSpace(` +These are the MD5 message digests for the files in this directory. +If you want to test your files, use 'md5sum' and compare the values to +the ones listed here. + +To test all these files, use this command: + +tail +13 CHECKSUMS.md5 | md5sum -c --quiet - | less + +'md5sum' can be found in the GNU coreutils package on ftp.gnu.org in +/pub/gnu, or at any GNU mirror site. + +MD5 message digest Filename +`) + +type ChecksumsEntry struct { + MD5 string + Filename string +} + +type Checksums struct { + Entries []ChecksumsEntry +} + +func OpenChecksums(filePath string) (*Checksums, error) { + f, err := os.Open(filePath) + if err != nil { + return nil, err + } + + buf, err := io.ReadAll(f) + if err != nil { + return nil, err + } + + var checksums Checksums + err = checksums.UnmarshalText(buf) + if err != nil { + return nil, err + } + + return &checksums, nil +} + +func (c *Checksums) Hash() hash.Hash { + return md5.New() +} + +func (c *Checksums) UnmarshalText(buf []byte) error { + r := bufio.NewReader(bytes.NewReader(buf)) + + for _, headerLine := range strings.Split(checksumsHeader, "\n") { + line, _, err := r.ReadLine() + if err != nil { + return err + } + + if string(line) != headerLine { + println(string(line)) + println(headerLine) + return errors.New("unexpected format") + } + } + + for { + line, _, err := r.ReadLine() + if err == io.EOF { + break + } else if err != nil { + return err + } + + fields := strings.Split(string(line), " ") + if len(fields) != 2 { + return errors.New("unexpected format") + } + c.Entries = append(c.Entries, ChecksumsEntry{ + MD5: fields[0], + Filename: fields[1], + }) + } + + return nil +} + +func (c *Checksums) HasFilePath(filePath string) bool { + filePath = path.Clean(filePath) + for _, entry := range c.Entries { + if entry.Filename == "./"+filePath { + return true + } + } + return false +} + +func (c *Checksums) Files() []string { + var entries []string + + for _, entry := range c.Entries { + entries = append(entries, entry.Filename) + } + + return entries +} + +func (c *Checksums) String() string { + str := strings.TrimSpace(checksumsHeader) + + for _, entry := range c.Entries { + line := fmt.Sprintf("%s %s", entry.MD5, entry.Filename) + str = str + "\n" + line + } + + return str +} + +func (c *Checksums) Verify(fileName string, sum []byte) (bool, error) { + fileName = path.Clean(fileName) + sumStr := fmt.Sprintf("%x", sum) + + for _, entry := range c.Entries { + if entry.Filename == "./"+fileName { + return entry.MD5 == sumStr, nil + } + } + + return false, errors.New("not found") +} |