now writes xattrs! on to Check()...

This commit is contained in:
Jeffrey Paul 2019-09-05 17:38:43 +02:00
parent 59bf39aa6d
commit 87d134a877

137
main.go
View File

@ -1,12 +1,15 @@
//3456789112345676892123456789312345678941234567895123456789612345678971234567898
package main package main
//import "crypto/sha256" import "crypto/sha256"
import "fmt" import "fmt"
import "github.com/sirupsen/logrus" import "github.com/sirupsen/logrus"
import "github.com/multiformats/go-multihash"
//import "github.com/pkg/xattr" import "github.com/mr-tron/base58"
import "hash" import "github.com/pkg/xattr"
import "os" import "os"
import "io"
import "flag" import "flag"
import "time" import "time"
@ -16,6 +19,16 @@ var Builduser string
var Buildarch string var Buildarch string
var log *logrus.Logger var log *logrus.Logger
const namespacePrefix = "berlin.sneak.xsum"
//FIXME(sneak) make this parallelize to NUM_CPUS when processing multiple
//args
//FIXME(sneak) add a -r (recursive) flag for directories
//FIXME(sneak) make checking support reading hash algo type from multihash
//instead of assumming sha256
func main() { func main() {
os.Exit(xsum()) os.Exit(xsum())
} }
@ -40,11 +53,9 @@ func xsum() int {
) )
paths := flag.Args() paths := flag.Args()
fmt.Printf("%+v\n", paths)
if len(paths) > 1 { if len(paths) > 1 {
paths = paths[1:] paths = paths[1:]
} }
fmt.Printf("%+v\n", paths)
switch flag.Arg(0) { switch flag.Arg(0) {
case "cron": case "cron":
return xsfCheckAndUpdate(paths) return xsfCheckAndUpdate(paths)
@ -67,20 +78,21 @@ func usage() {
func xsfCheck(paths []string) int { func xsfCheck(paths []string) int {
log.Debugf("check") log.Debugf("check")
log.Fatalf("not implemented")
return 0 return 0
} }
func showError(e *error) { func showError(e error) {
fmt.Fprintf(os.Stderr, "error: %s\n", e) fmt.Fprintf(os.Stderr, "error: %s\n", e)
} }
func xsfUpdate(paths []string) int { func xsfUpdate(paths []string) int {
log.Debugf("update") log.Debugf("update")
for _, path := range paths { for _, path := range paths {
x := NewXsf(path) x := newXsf(path)
err := x.Update() err := x.Update()
if err != nil { if err != nil {
showError(&err) showError(err)
return -1 return -1
} }
} }
@ -96,17 +108,89 @@ func xsfCheckAndUpdate(paths []string) int {
return xsfUpdate(paths) return xsfUpdate(paths)
} }
func HashFile(fp *os.File) (string, error) {
h := sha256.New()
if _, err := io.Copy(h, fp); err != nil {
return "", err
}
mHashBuf, err := multihash.EncodeName(h.Sum(nil), "sha1")
if err != nil {
return "", err
}
return base58.Encode(mHashBuf), nil
}
/////////////////////////////////////////////////////////////////////////////////
// type xsf
/////////////////////////////////////////////////////////////////////////////////
type xsf struct { type xsf struct {
path string
mtime *time.Time
size int64
sum *hash.Hash
fi *os.FileInfo fi *os.FileInfo
fp *os.File
hash string
mtime string
path string
size int64
}
/////////////////////////////////////////////////////////////////////////////////
// constructor
/////////////////////////////////////////////////////////////////////////////////
type xsf struct {
fi *os.FileInfo
fp *os.File
hash string
mtime string
path string
size int64
}
func newXsf(path string) *xsf {
x := xsf{}
x.path = path
return &x
}
func (x *xsf) writeXattrs(fp *os.File) error {
log.Infof("writing xattrs")
var xn string
var err error
xn = fmt.Sprintf("%s.%s", namespacePrefix, "mtime")
log.Infof("writing xattr %s=%s", xn, x.mtime)
err = xattr.FSet(fp, xn, []byte(x.mtime))
if err != nil {
return err
}
xn = fmt.Sprintf("%s.%s", namespacePrefix, "size")
log.Infof("writing xattr %s=%s", xn, fmt.Sprintf("%d", x.size))
err = xattr.FSet(fp, xn, []byte(fmt.Sprintf("%d", x.size)))
if err != nil {
return err
}
xn = fmt.Sprintf("%s.%s", namespacePrefix, "multihash")
log.Infof("writing xattr %s=%s", xn, x.hash)
err = xattr.FSet(fp, xn, []byte(x.hash))
if err != nil {
return err
}
return nil
} }
func (x *xsf) Update() error { func (x *xsf) Update() error {
fp, e1 := os.Open(x.path) fp, e1 := os.Open(x.path)
defer fp.Close() defer fp.Close()
log.Infof("updating file")
log.Debugf("path: %s", x.path)
if e1 != nil { if e1 != nil {
return e1 return e1
} }
@ -116,13 +200,24 @@ func (x *xsf) Update() error {
return e2 return e2
} }
x.size = fi.Size() x.size = fi.Size()
t := fi.ModTime() log.Debugf("size: %d", x.size)
x.mtime = &t t := fi.ModTime().UTC().Format(time.RFC3339)
log.Debugf("modtime: %s", t)
x.mtime = t
log.Debugf("hashing...")
h, e3 := HashFile(fp)
if e3 != nil {
return e3
}
x.hash = h
log.Debugf("hash: %s", h)
e4 := x.writeXattrs(fp)
if e4 != nil {
return e4
}
return nil return nil
} }
func NewXsf(path string) *xsf {
x := xsf{}
x.path = path
return &x
}