diff --git a/pkg/schema/schema.go b/pkg/schema/schema.go index a1621af65..e6454ba73 100644 --- a/pkg/schema/schema.go +++ b/pkg/schema/schema.go @@ -384,7 +384,7 @@ func NewFileMap(fileName string) map[string]interface{} { } func NewCommonFilenameMap(fileName string) map[string]interface{} { - m := newCamliMap(1, "" /* no type yet */ ) + m := newCamliMap(1, "" /* no type yet */) if fileName != "" { lastSlash := strings.LastIndex(fileName, "/") baseName := fileName[lastSlash+1:] @@ -397,12 +397,20 @@ func NewCommonFilenameMap(fileName string) map[string]interface{} { return m } +var populateSchemaStat []func(schemaMap map[string]interface{}, fi os.FileInfo) + func NewCommonFileMap(fileName string, fi os.FileInfo) map[string]interface{} { m := NewCommonFilenameMap(fileName) // Common elements (from file-common.txt) - if fi.Mode() & os.ModeSymlink != 0 { + if fi.Mode()&os.ModeSymlink != 0 { m["unixPermission"] = fmt.Sprintf("0%o", fi.Mode().Perm()) } + + // OS-specific population; defined in schema_posix.go, etc. (not on App Engine) + for _, f := range populateSchemaStat { + f(m, fi) + } + /** TODO-GO1(bradfitz): this will need to do fi.Sys().(*syscall....), but syscall can't run on App Engine, so will need build context tags for @@ -427,7 +435,7 @@ func NewCommonFileMap(fileName string, fi os.FileInfo) map[string]interface{} { */ if mtime := fi.ModTime(); !mtime.IsZero() { m["unixMtime"] = RFC3339FromTime(mtime) - } + } return m } diff --git a/pkg/schema/schema_posix.go b/pkg/schema/schema_posix.go new file mode 100644 index 000000000..46bdcae83 --- /dev/null +++ b/pkg/schema/schema_posix.go @@ -0,0 +1,39 @@ +//+build linux darwin netbsd freebsd openbsd +//+build !appengine + +package schema + +import ( + "os" + "syscall" +) + +var _ = syscall.Close + +func init() { + populateSchemaStat = append(populateSchemaStat, populateSchemaUnix) +} + +func populateSchemaUnix(m map[string]interface{}, fi os.FileInfo) { + st, ok := fi.Sys().(*syscall.Stat_t) + if !ok { + return + } + m["unixOwnerId"] = st.Uid + if user := getUserFromUid(int(st.Uid)); user != "" { + m["unixOwner"] = user + } + m["unixGroupId"] = st.Gid + if group := getGroupFromGid(int(st.Gid)); group != "" { + m["unixGroup"] = group + } + /** + TODO-GO1(bradfitz): port this too. + + // Include the ctime too, if it differs. + if ctime := fi.Ctime_ns; ctime != 0 && fi.ModTime() != fi.Ctime_ns { + m["unixCtime"] = RFC3339FromTime(ctime) + } + */ + +}