tar_time: treat time from tar archives special

Since the field in a tar header for each file only preserves seconds
precision, not nanosecond precision, let's handle it special. This will
allow for more custom case handling in Check()

Signed-off-by: Vincent Batts <vbatts@hashbangbash.com>
This commit is contained in:
Vincent Batts 2016-07-22 15:53:05 -04:00 committed by Stephen Chung
parent decc72b335
commit bc6f3bf902
2 changed files with 18 additions and 0 deletions

View File

@ -160,6 +160,11 @@ var (
"sha512": hasherKeywordFunc("sha512", sha512.New), // The SHA512 message digest of the file
"sha512digest": hasherKeywordFunc("sha512digest", sha512.New), // A synonym for `sha512`
// This is not an upstreamed keyword, but used to vary from "time", as tar
// archives do not store nanosecond precision. So comparing on "time" will
// be only seconds level accurate.
"tar_time": tartimeKeywordFunc, // The last modification time of the file, from a tar archive mtime
// 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.
@ -207,6 +212,13 @@ var (
return fmt.Sprintf("%s=%x", name, h.Sum(nil)), nil
}
}
tartimeKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) {
t := info.ModTime().Unix()
if t == 0 {
return "tar_time=0.000000000", nil
}
return fmt.Sprintf("tar_time=%d.000000000", t), nil
}
timeKeywordFunc = func(path string, info os.FileInfo, r io.Reader) (string, error) {
t := info.ModTime().UnixNano()
if t == 0 {

6
tar.go
View File

@ -102,6 +102,9 @@ func (ts *tarStream) readHeaders() {
// now collect keywords on the file
for _, keyword := range ts.keywords {
if keyword == "time" {
keyword = "tar_time"
}
if keyFunc, ok := KeywordFuncs[keyword]; ok {
// We can't extract directories on to disk, so "size" keyword
// is irrelevant for now
@ -140,6 +143,9 @@ func (ts *tarStream) readHeaders() {
Type: SpecialType,
}
for _, setKW := range SetKeywords {
if setKW == "time" {
setKW = "tar_time"
}
if keyFunc, ok := KeywordFuncs[setKW]; ok {
val, err := keyFunc(hdr.Name, hdr.FileInfo(), tmpFile)
if err != nil {