keywords: added experimental "xattr" keyword
Initially only on linux platform, but could accommodate BSDs as well. The keyword is rather a prefix of the key. So xattr keyword will have a prefix of "xattr." followed by a suffix of its namespace and name. The value stored in the manifest is the SHA1 digest of the extended attribute's data. Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
parent
2d3aea8623
commit
211687bcc4
5 changed files with 34 additions and 2 deletions
|
@ -55,6 +55,12 @@ var (
|
||||||
"sha384digest": hasherKeywordFunc("sha384digest", sha512.New384), // A synonym for `sha384`
|
"sha384digest": hasherKeywordFunc("sha384digest", sha512.New384), // A synonym for `sha384`
|
||||||
"sha512": hasherKeywordFunc("sha512", sha512.New), // The SHA512 message digest of the file
|
"sha512": hasherKeywordFunc("sha512", sha512.New), // The SHA512 message digest of the file
|
||||||
"sha512digest": hasherKeywordFunc("sha512digest", sha512.New), // A synonym for `sha512`
|
"sha512digest": hasherKeywordFunc("sha512digest", sha512.New), // A synonym for `sha512`
|
||||||
|
|
||||||
|
// This is not an upstreamed keyword, but a needed attribute for file validation.
|
||||||
|
// The pattern for this keyword key is prefixed by "xattr." followed by the extended attribute "namespace.key".
|
||||||
|
// The keyword value is the SHA1 digest of the extended attribute's value.
|
||||||
|
// In this way, the order of the keys does not matter, and the contents of the value is not revealed.
|
||||||
|
"xattr": xattrKeywordFunc,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,14 @@
|
||||||
package mtree
|
package mtree
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/sha1"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
|
"strings"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
|
"./xattr"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -30,4 +34,20 @@ var (
|
||||||
stat := info.Sys().(*syscall.Stat_t)
|
stat := info.Sys().(*syscall.Stat_t)
|
||||||
return fmt.Sprintf("nlink=%d", stat.Nlink), nil
|
return fmt.Sprintf("nlink=%d", stat.Nlink), nil
|
||||||
}
|
}
|
||||||
|
xattrKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||||
|
xlist, err := xattr.List(path)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
klist := make([]string, len(xlist))
|
||||||
|
for i := range xlist {
|
||||||
|
data, err := xattr.Get(path, xlist[i])
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
println(string(data))
|
||||||
|
klist[i] = fmt.Sprintf("xattr.%s=%x", xlist[i], sha1.Sum(data))
|
||||||
|
}
|
||||||
|
return strings.Join(klist, " "), nil
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
|
@ -17,4 +17,7 @@ var (
|
||||||
nlinkKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
nlinkKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
xattrKeywordFunc = func(path string, info os.FileInfo) (string, error) {
|
||||||
|
return "", nil
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
|
5
walk.go
5
walk.go
|
@ -15,6 +15,8 @@ type ExcludeFunc func(path string, info os.FileInfo) bool
|
||||||
// need a more linear walk, which this can not ensure.
|
// need a more linear walk, which this can not ensure.
|
||||||
func Walk(root string, exlcudes []ExcludeFunc, keywords []string) (*DirectoryHierarchy, error) {
|
func Walk(root string, exlcudes []ExcludeFunc, keywords []string) (*DirectoryHierarchy, error) {
|
||||||
dh := DirectoryHierarchy{}
|
dh := DirectoryHierarchy{}
|
||||||
|
count := 0
|
||||||
|
// TODO insert signature and metadata comments first
|
||||||
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
err := filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -27,6 +29,7 @@ func Walk(root string, exlcudes []ExcludeFunc, keywords []string) (*DirectoryHie
|
||||||
e := Entry{}
|
e := Entry{}
|
||||||
//e.Name = filepath.Base(path)
|
//e.Name = filepath.Base(path)
|
||||||
e.Name = path
|
e.Name = path
|
||||||
|
e.Pos = count
|
||||||
for _, keyword := range keywords {
|
for _, keyword := range keywords {
|
||||||
if str, err := KeywordFuncs[keyword](path, info); err == nil && str != "" {
|
if str, err := KeywordFuncs[keyword](path, info); err == nil && str != "" {
|
||||||
e.Keywords = append(e.Keywords, str)
|
e.Keywords = append(e.Keywords, str)
|
||||||
|
@ -34,8 +37,8 @@ func Walk(root string, exlcudes []ExcludeFunc, keywords []string) (*DirectoryHie
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// XXX
|
|
||||||
dh.Entries = append(dh.Entries, e)
|
dh.Entries = append(dh.Entries, e)
|
||||||
|
count++
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return &dh, err
|
return &dh, err
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestWalk(t *testing.T) {
|
func TestWalk(t *testing.T) {
|
||||||
dh, err := Walk(".", nil, append(DefaultKeywords, "cksum", "md5", "rmd160digest", "sha1", "sha256", "sha512"))
|
dh, err := Walk(".", nil, append(DefaultKeywords, "xattr"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue