-
Notifications
You must be signed in to change notification settings - Fork 0
/
fp.go
108 lines (92 loc) · 2.01 KB
/
fp.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
package main
import (
"bytes"
"crypto/md5"
"crypto/sha1"
"crypto/sha256"
"encoding/hex"
"flag"
"fmt"
"hash"
"io"
"log"
"os"
"strings"
"github.com/atotto/clipboard"
)
// DigestGroup hashes a file for a given path
func DigestGroup(hg map[string]hash.Hash, loc string) (map[string]string, error) {
var fns []io.Writer
for _, fn := range hg {
fns = append(fns, fn)
}
w := io.MultiWriter(fns...)
file, err := os.Open(loc)
if err != nil {
return nil, err
}
defer file.Close()
buf := make([]byte, 1024)
if _, err := io.CopyBuffer(w, file, buf); err != nil {
return nil, err
}
out := make(map[string]string)
for name, v := range hg {
out[name] = hex.EncodeToString(v.Sum(nil))
}
return out, nil
}
func usage() {
fmt.Fprintf(os.Stderr, "Usage: fp [file or directory]\n")
fmt.Fprintf(os.Stderr, "\nThis command allows you to view information about a specified file or directory.\n")
fmt.Fprintf(os.Stderr, "\nFlags:\n")
flag.PrintDefaults()
os.Exit(2)
}
var (
flagVerbose = flag.Bool("d", false, `Print detailed file hash information, including the md5, sha1, and sha256 hashes`)
flagClip = flag.Bool("c", false, "Copy the path to the clipboard")
)
func main() {
log.SetPrefix("fp: ")
log.SetFlags(0)
flag.Usage = usage
flag.Parse()
if flag.NArg() == 0 {
flag.Usage()
}
path := flag.Arg(0)
abs, fi, err := ReadFileInfo(path)
if err != nil {
log.Fatal(err)
}
rr := NewRowRender()
if *flagVerbose {
if fi.IsDir() {
rr.AddRow("DIR", abs)
} else {
rr.AddRow("FILE", abs)
}
rr.AddRow("SIZE", ByteCountSI(fi.Size()))
hg := make(map[string]hash.Hash)
hg["MD5"] = md5.New()
hg["SHA1"] = sha1.New()
hg["SHA256"] = sha256.New()
values, err := DigestGroup(hg, abs)
if err != nil {
log.Fatal("unable to digest group: ", err)
}
rr.AddRowMap(values)
rr.Write(os.Stdout)
return
}
rr.AddRow("", abs)
if *flagClip {
buf := new(bytes.Buffer)
rr.Write(buf)
line := buf.String()
clipboard.WriteAll(strings.TrimSuffix(line, "\n"))
return
}
rr.Write(os.Stdout)
}