aboutsummaryrefslogtreecommitdiff
path: root/internal/slackware_com/checksums.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/slackware_com/checksums.go')
-rw-r--r--internal/slackware_com/checksums.go143
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")
+}