2017-11-16 16:22:46 +00:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"flag"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
|
2023-05-04 20:58:43 +00:00
|
|
|
"git.wntrmute.dev/kyle/goutils/ahash"
|
|
|
|
"git.wntrmute.dev/kyle/goutils/die"
|
|
|
|
"git.wntrmute.dev/kyle/goutils/lib"
|
2017-11-16 16:22:46 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func usage(w io.Writer) {
|
|
|
|
fmt.Fprintf(w, `Usage: %s [-a algo] [-h] [-l set] urls...
|
|
|
|
Compute the hash over each URL.
|
|
|
|
|
|
|
|
Flags:
|
|
|
|
-a algo Specify the hash algorithm to use; the default is sha256.
|
|
|
|
-h Print this help message.
|
|
|
|
-l set List the hash functions under set. Set can be one of all,
|
|
|
|
secure to list only cryptographic hash functions, or
|
|
|
|
insecure to list only non-cryptographic hash functions.
|
|
|
|
|
|
|
|
`, lib.ProgName())
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
flag.Usage = func() { usage(os.Stderr) }
|
|
|
|
}
|
|
|
|
|
|
|
|
func main() {
|
|
|
|
var algo, list string
|
|
|
|
var help bool
|
|
|
|
flag.StringVar(&algo, "a", "sha256", "hash algorithm to use")
|
|
|
|
flag.BoolVar(&help, "h", false, "print a help message")
|
|
|
|
flag.StringVar(&list, "l", "", "list known hash algorithms (one of all, secure, insecure)")
|
|
|
|
flag.Parse()
|
2017-11-16 16:26:27 +00:00
|
|
|
|
2017-11-16 16:22:46 +00:00
|
|
|
if help {
|
|
|
|
usage(os.Stdout)
|
|
|
|
}
|
|
|
|
|
|
|
|
if list != "" {
|
|
|
|
var hashes []string
|
|
|
|
switch list {
|
|
|
|
case "all":
|
|
|
|
hashes = ahash.HashList()
|
|
|
|
case "secure":
|
|
|
|
hashes = ahash.SecureHashList()
|
|
|
|
case "insecure":
|
|
|
|
hashes = ahash.InsecureHashList()
|
|
|
|
default:
|
|
|
|
die.With("list option must be one of all, secure, or insecure.")
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, algo := range hashes {
|
|
|
|
fmt.Printf("- %s\n", algo)
|
|
|
|
}
|
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, remote := range flag.Args() {
|
|
|
|
u, err := url.Parse(remote)
|
|
|
|
if err != nil {
|
|
|
|
lib.Warn(err, "parsing %s", remote)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
|
|
|
name := filepath.Base(u.Path)
|
|
|
|
if name == "" {
|
|
|
|
lib.Warnx("source URL doesn't appear to name a file")
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-11-18 02:55:20 +00:00
|
|
|
resp, err := http.Get(remote)
|
|
|
|
if err != nil {
|
|
|
|
lib.Warn(err, "fetching %s", remote)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-11-16 16:22:46 +00:00
|
|
|
if err != nil {
|
|
|
|
lib.Warn(err, "fetching %s", remote)
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
|
2017-11-18 02:55:20 +00:00
|
|
|
sum, err := ahash.SumReader(algo, resp.Body)
|
|
|
|
resp.Body.Close()
|
2017-11-16 16:22:46 +00:00
|
|
|
if err != nil {
|
|
|
|
lib.Err(lib.ExitFailure, err, "while hashing data")
|
|
|
|
}
|
|
|
|
fmt.Printf("%s: %s=%x\n", name, algo, sum)
|
|
|
|
}
|
|
|
|
}
|