if *verbose {
log.Printf("adding to tar: %s", name)
}
- hdr, err := tarFileInfoHeader(fi, path)
+ target, _ := os.Readlink(path)
+ hdr, err := tar.FileInfoHeader(fi, target)
if err != nil {
return err
}
}
return
}
-
-// sysStat, if non-nil, populates h from system-dependent fields of fi.
-var sysStat func(fi os.FileInfo, h *tar.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
-)
-
-// tarFileInfoHeader creates a partially-populated Header from an os.FileInfo.
-// The filename parameter is used only in the case of symlinks, to call os.Readlink.
-// If fi is a symlink but filename is empty, an error is returned.
-func tarFileInfoHeader(fi os.FileInfo, filename string) (*tar.Header, error) {
- h := &tar.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 = tar.TypeReg
- h.Size = fi.Size()
- case fi.IsDir():
- h.Typeflag = tar.TypeDir
- h.Mode |= c_ISDIR
- case fi.Mode()&os.ModeSymlink != 0:
- h.Typeflag = tar.TypeSymlink
- h.Mode |= c_ISLNK
- if filename == "" {
- return h, fmt.Errorf("archive/tar: unable to populate Header.Linkname of symlinks")
- }
- targ, err := os.Readlink(filename)
- if err != nil {
- return h, err
- }
- h.Linkname = targ
- case fi.Mode()&os.ModeDevice != 0:
- if fi.Mode()&os.ModeCharDevice != 0 {
- h.Mode |= c_ISCHR
- h.Typeflag = tar.TypeChar
- } else {
- h.Mode |= c_ISBLK
- h.Typeflag = tar.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
-}
+++ /dev/null
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build darwin
-
-package main
-
-import (
- "archive/tar"
- "os"
- "syscall"
- "time"
-)
-
-func init() {
- sysStat = func(fi os.FileInfo, h *tar.Header) error {
- sys, ok := fi.Sys().(*syscall.Stat_t)
- if !ok {
- return nil
- }
- h.Uid = int(sys.Uid)
- h.Gid = int(sys.Gid)
- // TODO(bradfitz): populate username & group. os/user
- // doesn't cache LookupId lookups, and lacks group
- // lookup functions.
- h.AccessTime = time.Unix(sys.Atimespec.Unix())
- h.ChangeTime = time.Unix(sys.Ctimespec.Unix())
- // TODO(bradfitz): major/minor device numbers?
- return nil
- }
-}
+++ /dev/null
-// Copyright 2012 The Go Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style
-// license that can be found in the LICENSE file.
-
-// +build linux
-
-package main
-
-import (
- "archive/tar"
- "os"
- "syscall"
- "time"
-)
-
-func init() {
- sysStat = func(fi os.FileInfo, h *tar.Header) error {
- sys, ok := fi.Sys().(*syscall.Stat_t)
- if !ok {
- return nil
- }
- h.Uid = int(sys.Uid)
- h.Gid = int(sys.Gid)
- // TODO(bradfitz): populate username & group. os/user
- // doesn't cache LookupId lookups, and lacks group
- // lookup functions.
- h.AccessTime = time.Unix(sys.Atim.Unix())
- h.ChangeTime = time.Unix(sys.Ctim.Unix())
- // TODO(bradfitz): major/minor device numbers?
- return nil
- }
-}