Skip to content

Commit 72df48d

Browse files
committed
vendor: add archive/tar
Signed-off-by: Tonis Tiigi <[email protected]>
1 parent f22cecf commit 72df48d

File tree

10 files changed

+1980
-0
lines changed

10 files changed

+1980
-0
lines changed

Dockerfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ RUN set -x \
107107
# IMPORTANT: If the version of Go is updated, the Windows to Linux CI machines
108108
# will need updating, to avoid errors. Ping #docker-maintainers on IRC
109109
# with a heads-up.
110+
# IMPORTANT: When updating this please note that stdlib archive/tar pkg is vendored
110111
ENV GO_VERSION 1.8.3
111112
RUN curl -fsSL "https://golang.org/dl/go${GO_VERSION}.linux-amd64.tar.gz" \
112113
| tar -xzC /usr/local

vendor.conf

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,3 +136,11 @@ github.com/Nvveen/Gotty a8b993ba6abdb0e0c12b0125c603323a71c7790c https://github.
136136
github.com/docker/go-metrics d466d4f6fd960e01820085bd7e1a24426ee7ef18
137137

138138
github.com/opencontainers/selinux v1.0.0-rc1
139+
140+
# archive/tar
141+
# mkdir -p ./vendor/archive
142+
# git clone git://github.com/tonistiigi/go-1.git ./go
143+
# git --git-dir ./go/.git --work-tree ./go checkout revert-prefix-ignore
144+
# cp -a go/src/archive/tar ./vendor/archive/tar
145+
# rm -rf ./go
146+
# vndr

vendor/archive/tar/common.go

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,286 @@
1+
// Copyright 2009 The Go Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style
3+
// license that can be found in the LICENSE file.
4+
5+
// Package tar implements access to tar archives.
6+
// It aims to cover most of the variations, including those produced
7+
// by GNU and BSD tars.
8+
//
9+
// References:
10+
// http://www.freebsd.org/cgi/man.cgi?query=tar&sektion=5
11+
// http://www.gnu.org/software/tar/manual/html_node/Standard.html
12+
// http://pubs.opengroup.org/onlinepubs/9699919799/utilities/pax.html
13+
package tar
14+
15+
import (
16+
"errors"
17+
"fmt"
18+
"os"
19+
"path"
20+
"time"
21+
)
22+
23+
// BUG: Use of the Uid and Gid fields in Header could overflow on 32-bit
24+
// architectures. If a large value is encountered when decoding, the result
25+
// stored in Header will be the truncated version.
26+
27+
// Header type flags.
28+
const (
29+
TypeReg = '0' // regular file
30+
TypeRegA = '\x00' // regular file
31+
TypeLink = '1' // hard link
32+
TypeSymlink = '2' // symbolic link
33+
TypeChar = '3' // character device node
34+
TypeBlock = '4' // block device node
35+
TypeDir = '5' // directory
36+
TypeFifo = '6' // fifo node
37+
TypeCont = '7' // reserved
38+
TypeXHeader = 'x' // extended header
39+
TypeXGlobalHeader = 'g' // global extended header
40+
TypeGNULongName = 'L' // Next file has a long name
41+
TypeGNULongLink = 'K' // Next file symlinks to a file w/ a long name
42+
TypeGNUSparse = 'S' // sparse file
43+
)
44+
45+
// A Header represents a single header in a tar archive.
46+
// Some fields may not be populated.
47+
type Header struct {
48+
Name string // name of header file entry
49+
Mode int64 // permission and mode bits
50+
Uid int // user id of owner
51+
Gid int // group id of owner
52+
Size int64 // length in bytes
53+
ModTime time.Time // modified time
54+
Typeflag byte // type of header entry
55+
Linkname string // target name of link
56+
Uname string // user name of owner
57+
Gname string // group name of owner
58+
Devmajor int64 // major number of character or block device
59+
Devminor int64 // minor number of character or block device
60+
AccessTime time.Time // access time
61+
ChangeTime time.Time // status change time
62+
Xattrs map[string]string
63+
}
64+
65+
// FileInfo returns an os.FileInfo for the Header.
66+
func (h *Header) FileInfo() os.FileInfo {
67+
return headerFileInfo{h}
68+
}
69+
70+
// headerFileInfo implements os.FileInfo.
71+
type headerFileInfo struct {
72+
h *Header
73+
}
74+
75+
func (fi headerFileInfo) Size() int64 { return fi.h.Size }
76+
func (fi headerFileInfo) IsDir() bool { return fi.Mode().IsDir() }
77+
func (fi headerFileInfo) ModTime() time.Time { return fi.h.ModTime }
78+
func (fi headerFileInfo) Sys() interface{} { return fi.h }
79+
80+
// Name returns the base name of the file.
81+
func (fi headerFileInfo) Name() string {
82+
if fi.IsDir() {
83+
return path.Base(path.Clean(fi.h.Name))
84+
}
85+
return path.Base(fi.h.Name)
86+
}
87+
88+
// Mode returns the permission and mode bits for the headerFileInfo.
89+
func (fi headerFileInfo) Mode() (mode os.FileMode) {
90+
// Set file permission bits.
91+
mode = os.FileMode(fi.h.Mode).Perm()
92+
93+
// Set setuid, setgid and sticky bits.
94+
if fi.h.Mode&c_ISUID != 0 {
95+
// setuid
96+
mode |= os.ModeSetuid
97+
}
98+
if fi.h.Mode&c_ISGID != 0 {
99+
// setgid
100+
mode |= os.ModeSetgid
101+
}
102+
if fi.h.Mode&c_ISVTX != 0 {
103+
// sticky
104+
mode |= os.ModeSticky
105+
}
106+
107+
// Set file mode bits.
108+
// clear perm, setuid, setgid and sticky bits.
109+
m := os.FileMode(fi.h.Mode) &^ 07777
110+
if m == c_ISDIR {
111+
// directory
112+
mode |= os.ModeDir
113+
}
114+
if m == c_ISFIFO {
115+
// named pipe (FIFO)
116+
mode |= os.ModeNamedPipe
117+
}
118+
if m == c_ISLNK {
119+
// symbolic link
120+
mode |= os.ModeSymlink
121+
}
122+
if m == c_ISBLK {
123+
// device file
124+
mode |= os.ModeDevice
125+
}
126+
if m == c_ISCHR {
127+
// Unix character device
128+
mode |= os.ModeDevice
129+
mode |= os.ModeCharDevice
130+
}
131+
if m == c_ISSOCK {
132+
// Unix domain socket
133+
mode |= os.ModeSocket
134+
}
135+
136+
switch fi.h.Typeflag {
137+
case TypeSymlink:
138+
// symbolic link
139+
mode |= os.ModeSymlink
140+
case TypeChar:
141+
// character device node
142+
mode |= os.ModeDevice
143+
mode |= os.ModeCharDevice
144+
case TypeBlock:
145+
// block device node
146+
mode |= os.ModeDevice
147+
case TypeDir:
148+
// directory
149+
mode |= os.ModeDir
150+
case TypeFifo:
151+
// fifo node
152+
mode |= os.ModeNamedPipe
153+
}
154+
155+
return mode
156+
}
157+
158+
// sysStat, if non-nil, populates h from system-dependent fields of fi.
159+
var sysStat func(fi os.FileInfo, h *Header) error
160+
161+
// Mode constants from the tar spec.
162+
const (
163+
c_ISUID = 04000 // Set uid
164+
c_ISGID = 02000 // Set gid
165+
c_ISVTX = 01000 // Save text (sticky bit)
166+
c_ISDIR = 040000 // Directory
167+
c_ISFIFO = 010000 // FIFO
168+
c_ISREG = 0100000 // Regular file
169+
c_ISLNK = 0120000 // Symbolic link
170+
c_ISBLK = 060000 // Block special file
171+
c_ISCHR = 020000 // Character special file
172+
c_ISSOCK = 0140000 // Socket
173+
)
174+
175+
// Keywords for the PAX Extended Header
176+
const (
177+
paxAtime = "atime"
178+
paxCharset = "charset"
179+
paxComment = "comment"
180+
paxCtime = "ctime" // please note that ctime is not a valid pax header.
181+
paxGid = "gid"
182+
paxGname = "gname"
183+
paxLinkpath = "linkpath"
184+
paxMtime = "mtime"
185+
paxPath = "path"
186+
paxSize = "size"
187+
paxUid = "uid"
188+
paxUname = "uname"
189+
paxXattr = "SCHILY.xattr."
190+
paxNone = ""
191+
)
192+
193+
// FileInfoHeader creates a partially-populated Header from fi.
194+
// If fi describes a symlink, FileInfoHeader records link as the link target.
195+
// If fi describes a directory, a slash is appended to the name.
196+
// Because os.FileInfo's Name method returns only the base name of
197+
// the file it describes, it may be necessary to modify the Name field
198+
// of the returned header to provide the full path name of the file.
199+
func FileInfoHeader(fi os.FileInfo, link string) (*Header, error) {
200+
if fi == nil {
201+
return nil, errors.New("tar: FileInfo is nil")
202+
}
203+
fm := fi.Mode()
204+
h := &Header{
205+
Name: fi.Name(),
206+
ModTime: fi.ModTime(),
207+
Mode: int64(fm.Perm()), // or'd with c_IS* constants later
208+
}
209+
switch {
210+
case fm.IsRegular():
211+
h.Mode |= c_ISREG
212+
h.Typeflag = TypeReg
213+
h.Size = fi.Size()
214+
case fi.IsDir():
215+
h.Typeflag = TypeDir
216+
h.Mode |= c_ISDIR
217+
h.Name += "/"
218+
case fm&os.ModeSymlink != 0:
219+
h.Typeflag = TypeSymlink
220+
h.Mode |= c_ISLNK
221+
h.Linkname = link
222+
case fm&os.ModeDevice != 0:
223+
if fm&os.ModeCharDevice != 0 {
224+
h.Mode |= c_ISCHR
225+
h.Typeflag = TypeChar
226+
} else {
227+
h.Mode |= c_ISBLK
228+
h.Typeflag = TypeBlock
229+
}
230+
case fm&os.ModeNamedPipe != 0:
231+
h.Typeflag = TypeFifo
232+
h.Mode |= c_ISFIFO
233+
case fm&os.ModeSocket != 0:
234+
h.Mode |= c_ISSOCK
235+
default:
236+
return nil, fmt.Errorf("archive/tar: unknown file mode %v", fm)
237+
}
238+
if fm&os.ModeSetuid != 0 {
239+
h.Mode |= c_ISUID
240+
}
241+
if fm&os.ModeSetgid != 0 {
242+
h.Mode |= c_ISGID
243+
}
244+
if fm&os.ModeSticky != 0 {
245+
h.Mode |= c_ISVTX
246+
}
247+
// If possible, populate additional fields from OS-specific
248+
// FileInfo fields.
249+
if sys, ok := fi.Sys().(*Header); ok {
250+
// This FileInfo came from a Header (not the OS). Use the
251+
// original Header to populate all remaining fields.
252+
h.Uid = sys.Uid
253+
h.Gid = sys.Gid
254+
h.Uname = sys.Uname
255+
h.Gname = sys.Gname
256+
h.AccessTime = sys.AccessTime
257+
h.ChangeTime = sys.ChangeTime
258+
if sys.Xattrs != nil {
259+
h.Xattrs = make(map[string]string)
260+
for k, v := range sys.Xattrs {
261+
h.Xattrs[k] = v
262+
}
263+
}
264+
if sys.Typeflag == TypeLink {
265+
// hard link
266+
h.Typeflag = TypeLink
267+
h.Size = 0
268+
h.Linkname = sys.Linkname
269+
}
270+
}
271+
if sysStat != nil {
272+
return h, sysStat(fi, h)
273+
}
274+
return h, nil
275+
}
276+
277+
// isHeaderOnlyType checks if the given type flag is of the type that has no
278+
// data section even if a size is specified.
279+
func isHeaderOnlyType(flag byte) bool {
280+
switch flag {
281+
case TypeLink, TypeSymlink, TypeChar, TypeBlock, TypeDir, TypeFifo:
282+
return true
283+
default:
284+
return false
285+
}
286+
}

0 commit comments

Comments
 (0)