From 146785207baa7f9029e91439ec41e176ccd0ef78 Mon Sep 17 00:00:00 2001 From: Sergey Matveev Date: Wed, 29 Sep 2021 22:46:58 +0300 Subject: [PATCH] Initial commit --- cmd/meta4-create/main.go | 141 +++++++++++++++++++++++++++++++++++++++ go.mod | 3 + 2 files changed, 144 insertions(+) create mode 100644 cmd/meta4-create/main.go create mode 100644 go.mod diff --git a/cmd/meta4-create/main.go b/cmd/meta4-create/main.go new file mode 100644 index 0000000..2289e8a --- /dev/null +++ b/cmd/meta4-create/main.go @@ -0,0 +1,141 @@ +/* +meta4a -- Metalink 4.0 utility +Copyright (C) 2021 Sergey Matveev + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, version 3 of the License. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ + +// Metalink 4.0 utility +package main + +import ( + "crypto/sha256" + "crypto/sha512" + "encoding/hex" + "encoding/xml" + "flag" + "io" + "io/ioutil" + "log" + "os" + "path/filepath" + "time" +) + +const ( + Generator = "meta4ra/0.1.0" + GPGSigMediaType = "application/pgp-signature" +) + +type Metalink struct { + XMLName xml.Name `xml:"urn:ietf:params:xml:ns:metalink metalink"` + Files []File `xml:"file"` + Generator string `xml:"generator,,omitempty"` + Published time.Time `xml:"published,,omitempty"` +} + +type File struct { + XMLName xml.Name `xml:"file"` + Name string `xml:"name,attr"` + Description string `xml:"description,,omitempty"` + Hashes []Hash `xml:"hash,,omitempty"` + MetaURLs []MetaURL `xml:"metaurl,,omitempty"` + Signature *Signature `xml:"signature"` + Size uint64 `xml:"size,,omitempty"` + URLs []URL `xml:"url,,omitempty"` +} + +type URL struct { + XMLName xml.Name `xml:"url"` + URL string `xml:",chardata"` +} + +type Signature struct { + XMLName xml.Name `xml:"signature"` + MediaType string `xml:"mediatype,attr"` + Signature string `xml:",cdata"` +} + +type Hash struct { + XMLName xml.Name `xml:"hash"` + Type string `xml:"type,attr"` + Hash string `xml:",chardata"` +} + +type MetaURL struct { + XMLName xml.Name `xml:"metaurl"` + MediaType string `xml:"mediatype,attr"` + URL string `xml:",chardata"` +} + +func main() { + file := flag.String("file", "", "Path to file") + desc := flag.String("desc", "", "Description") + sig := flag.String("sig", "", "Path to signature file") + torrent := flag.String("torrent", "", "Torrent URL") + log.SetFlags(log.Lshortfile) + flag.Parse() + urls := make([]URL, 0, len(flag.Args())) + for _, u := range flag.Args() { + urls = append(urls, URL{URL: u}) + } + fd, err := os.Open(*file) + if err != nil { + log.Fatalln(err) + } + fi, err := fd.Stat() + if err != nil { + log.Fatalln(err) + } + sha256Hasher := sha256.New() + sha512Hasher := sha512.New() + _, err = io.Copy(io.MultiWriter(sha256Hasher, sha512Hasher), fd) + if err != nil { + log.Fatalln(err) + } + f := File{ + Name: filepath.Base(*file), + Description: *desc, + Size: uint64(fi.Size()), + URLs: urls, + Hashes: []Hash{ + {Type: "sha-256", Hash: hex.EncodeToString(sha256Hasher.Sum(nil))}, + {Type: "sha-512", Hash: hex.EncodeToString(sha512Hasher.Sum(nil))}, + }, + } + if *sig != "" { + sigData, err := ioutil.ReadFile(*sig) + if err != nil { + log.Fatalln(err) + } + f.Signature = &Signature{ + MediaType: GPGSigMediaType, + Signature: "\n" + string(sigData), + } + } + if *torrent != "" { + f.MetaURLs = []MetaURL{{MediaType: "torrent", URL: *torrent}} + } + m := Metalink{ + Files: []File{f}, + Generator: Generator, + Published: time.Now().UTC().Truncate(time.Second), + } + out, err := xml.MarshalIndent(&m, "", " ") + if err != nil { + log.Fatalln(err) + } + os.Stdout.Write([]byte(xml.Header)) + os.Stdout.Write(out) + os.Stdout.Write([]byte("\n")) +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..1191e6f --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module go.stargrave.org/meta4ra + +go 1.17 -- 2.44.0