From bc6f3bf9021d961dae26537a579d74cf6e8030e0 Mon Sep 17 00:00:00 2001 From: Vincent Batts Date: Fri, 22 Jul 2016 15:53:05 -0400 Subject: [PATCH] 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 --- keywords.go | 12 ++++++++++++ tar.go | 6 ++++++ 2 files changed, 18 insertions(+) diff --git a/keywords.go b/keywords.go index f00a331..7bf199c 100644 --- a/keywords.go +++ b/keywords.go @@ -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 { diff --git a/tar.go b/tar.go index 5be607a..36b0f46 100644 --- a/tar.go +++ b/tar.go @@ -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 {