1
0
Fork 0

verify: starts of a checking function

This commit is contained in:
Vincent Batts 2015-10-29 15:30:47 -04:00
parent 5c8d5cacba
commit 867071d1e5
4 changed files with 158 additions and 45 deletions

View File

@ -0,0 +1,31 @@
// +build ignore
package main
import (
"fmt"
"os"
verify "."
)
func main() {
for _, arg := range os.Args[1:] {
keys, err := verify.Listxattr(arg)
if err != nil {
fmt.Println(err)
continue
}
if len(keys) > 0 {
fmt.Printf("%s : %q\n", arg, keys)
for _, key := range keys {
buf, err := verify.Lgetxattr(arg, key)
if err != nil {
fmt.Printf(" ERROR: %s\n", err)
continue
}
fmt.Printf(" %s = %s\n", key, string(buf))
}
}
}
}

View File

@ -1,23 +1,100 @@
package verify
import "time"
import (
"os"
"path/filepath"
"strings"
"time"
)
// PosixHeader is the structure from a POSIX tar header, to be marshalled from
// the tar stream, and available for on-disk comparison and verification
type PosixHeader struct {
Name string `json:"name,omitempty"`
Mode uint32 `json:"mode,omitempty"`
UID uint32 `json:"uid,omitempty"`
GID uint32 `json:"gid,omitempty"`
Size int `json:"size,omitempty"`
Mtime time.Time `json:"mtime,omitempty"`
Checksum []byte `json:"chksum,omitempty"`
LinkName string `json:"linkname,omitempty"`
Magic []byte `json:"magic,omitempty"`
Version string `json:"version,omitempty"`
Uname string `json:"uname,omitempty"`
Gname string `json:"gname,omitempty"`
DevMajor int `json:"devmajor,omitempty"`
DevMinor int `json:"devminor,omitempty"`
Prefix string `json:"prefix,omitempty"`
Name string `json:"name,omitempty"`
Mode os.FileMode `json:"mode,omitempty"`
UID uint32 `json:"uid,omitempty"`
GID uint32 `json:"gid,omitempty"`
Size int64 `json:"size,omitempty"`
Mtime time.Time `json:"mtime,omitempty"`
Checksum []byte `json:"chksum,omitempty"`
LinkName string `json:"linkname,omitempty"`
Magic []byte `json:"magic,omitempty"`
Version string `json:"version,omitempty"`
Uname string `json:"uname,omitempty"`
Gname string `json:"gname,omitempty"`
DevMajor int `json:"devmajor,omitempty"`
DevMinor int `json:"devminor,omitempty"`
Prefix string `json:"prefix,omitempty"`
}
type PaxHeader struct {
Atime time.Time
Ctime time.Time
Xattrs map[string]string
}
type Header struct {
// maybe I do not want these grouped like this. Maybe this should be an interface instead.
Posix PosixHeader
Pax PaxHeader
}
// Size returns file size (implements Sizer)
func (hdr Header) Size() int64 {
return int64(hdr.Posix.Size)
}
// ModTime returns file mtime (implements ModTimer)
func (hdr Header) ModTime() time.Time {
return hdr.Posix.Mtime
}
// Mode returns file mode (implements Moder)
func (hdr Header) Mode() os.FileMode {
return hdr.Posix.Mode
}
func (hdr Header) LinkName() string {
return hdr.Posix.LinkName
}
// HeaderFromFile takes a relative root and the filename of the file to collect
// information on.
func HeaderFromFile(rel, filename string) (*Header, error) {
absRel, err := filepath.Abs(rel)
if err != nil {
return nil, err
}
if strings.HasPrefix(filename, "/") {
var err error
filename, err = filepath.Abs(filename)
if err != nil {
return nil, err
}
}
stat, err := os.Lstat(filename)
if err != nil {
return nil, err
}
name := filename
if strings.HasPrefix(filename, absRel) {
name = strings.TrimPrefix(filename, absRel)
}
hdr := Header{
Posix: PosixHeader{
Name: name,
Size: stat.Size(),
Mode: stat.Mode(),
Mtime: stat.ModTime(),
},
}
if stat.Mode()&os.ModeSymlink != 0 {
l, _ := os.Readlink(filename) // if this errors, the empty string is OK
hdr.Posix.LinkName = l
}
return &hdr, nil
}

View File

@ -1,6 +1,10 @@
package verify
import "fmt"
import (
"fmt"
"os"
"time"
)
// CheckType is how the on disk attributes will be verified against the
// recorded header information
@ -15,14 +19,15 @@ const (
CheckFileUser
CheckFileGroup
CheckFileMtime
CheckFileDevice
CheckFileLink
CheckFileCaps
CheckFileDevice // major/minor
CheckFileLink // linkname
CheckFileCaps // which is just a subset of xattrs on linux
)
var (
// DefaultChecks is the default for verfication steps against each
// storage.VerficationEntry
// storage.VerficationEntry.
// These may need to vary from platform to platform
DefaultChecks = CheckDigest | CheckFileAttributes
// CheckFileAttributes are the group of file attribute checks done
CheckFileAttributes = CheckFileSize | CheckFileMode | CheckFileUser |
@ -32,3 +37,26 @@ var (
// ErrNotSupportedPlatform is when the platform does not support given features
ErrNotSupportedPlatform = fmt.Errorf("platform does not support this feature")
)
// FileAttrer exposes the functions corresponding to file attribute checks
type FileAttrer interface {
Sizer
Moder
ModTimer
LinkName() string
}
// Sizer returns the size of the file (see also os.FileInfo)
type Sizer interface {
Size() int64
}
// Moder returns the mode of the file (see also os.FileInfo)
type Moder interface {
Mode() os.FileMode
}
// ModTimer returns the mtime of the file (see also os.FileInfo)
type ModTimer interface {
ModTime() time.Time
}

View File

@ -13,29 +13,6 @@ import (
"unsafe"
)
/*
func main() {
for _, arg := range os.Args[1:] {
keys, err := Listxattr(arg)
if err != nil {
fmt.Println(err)
continue
}
if len(keys) > 0 {
fmt.Printf("%s : %q\n", arg, keys)
for _, key := range keys {
buf, err := Lgetxattr(arg, key)
if err != nil {
fmt.Printf(" ERROR: %s\n", err)
continue
}
fmt.Printf(" %s = %s\n", key, string(buf))
}
}
}
}
*/
// Listxattr is a helper around the syscall.Listxattr
func Listxattr(path string) ([]string, error) {
buf := make([]byte, 1024)
@ -48,7 +25,7 @@ func Listxattr(path string) ([]string, error) {
sz, err = syscall.Listxattr(path, buf)
}
keys := []string{}
for _, key := range bytes.Split(bytes.TrimSpace(buf), []byte{0x0}) {
for _, key := range bytes.Split(bytes.Trim(buf, "\x00"), []byte{0x0}) {
if string(key) != "" {
keys = append(keys, string(key))
}