diff options
Diffstat (limited to 'libgo/go/archive/tar/common.go')
-rw-r--r-- | libgo/go/archive/tar/common.go | 63 |
1 files changed, 62 insertions, 1 deletions
diff --git a/libgo/go/archive/tar/common.go b/libgo/go/archive/tar/common.go index fc7a40923cd..921b9fe9bdd 100644 --- a/libgo/go/archive/tar/common.go +++ b/libgo/go/archive/tar/common.go @@ -11,7 +11,12 @@ // http://www.gnu.org/software/tar/manual/html_node/Standard.html package tar -import "time" +import ( + "errors" + "fmt" + "os" + "time" +) const ( blockSize = 512 @@ -49,6 +54,62 @@ type Header struct { ChangeTime time.Time // status change time } +// sysStat, if non-nil, populates h from system-dependent fields of fi. +var sysStat func(fi os.FileInfo, h *Header) error + +// Mode constants from the tar spec. +const ( + c_ISDIR = 040000 + c_ISFIFO = 010000 + c_ISREG = 0100000 + c_ISLNK = 0120000 + c_ISBLK = 060000 + c_ISCHR = 020000 + c_ISSOCK = 0140000 +) + +// FileInfoHeader creates a partially-populated Header from fi. +// If fi describes a symlink, FileInfoHeader records link as the link target. +func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) { + if fi == nil { + return nil, errors.New("tar: FileInfo is nil") + } + h := &Header{ + Name: fi.Name(), + ModTime: fi.ModTime(), + Mode: int64(fi.Mode().Perm()), // or'd with c_IS* constants later + } + switch { + case fi.Mode()&os.ModeType == 0: + h.Mode |= c_ISREG + h.Typeflag = TypeReg + h.Size = fi.Size() + case fi.IsDir(): + h.Typeflag = TypeDir + h.Mode |= c_ISDIR + case fi.Mode()&os.ModeSymlink != 0: + h.Typeflag = TypeSymlink + h.Mode |= c_ISLNK + h.Linkname = link + case fi.Mode()&os.ModeDevice != 0: + if fi.Mode()&os.ModeCharDevice != 0 { + h.Mode |= c_ISCHR + h.Typeflag = TypeChar + } else { + h.Mode |= c_ISBLK + h.Typeflag = TypeBlock + } + case fi.Mode()&os.ModeSocket != 0: + h.Mode |= c_ISSOCK + default: + return nil, fmt.Errorf("archive/tar: unknown file mode %v", fi.Mode()) + } + if sysStat != nil { + return h, sysStat(fi, h) + } + return h, nil +} + var zeroBlock = make([]byte, blockSize) // POSIX specifies a sum of the unsigned byte values, but the Sun tar uses signed byte values. |