aboutsummaryrefslogtreecommitdiffhomepage
path: root/vendor/github.com/hashicorp/go-getter/decompress_tar.go
diff options
context:
space:
mode:
authorAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
committerAlex Pilon <apilon@hashicorp.com>2019-02-22 18:24:37 -0500
commit15c0b25d011f37e7c20aeca9eaf461f78285b8d9 (patch)
tree255c250a5c9d4801c74092d33b7337d8c14438ff /vendor/github.com/hashicorp/go-getter/decompress_tar.go
parent07971ca38143c5faf951d152fba370ddcbe26ad5 (diff)
downloadterraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.gz
terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.tar.zst
terraform-provider-statuscake-15c0b25d011f37e7c20aeca9eaf461f78285b8d9.zip
deps: github.com/hashicorp/terraform@sdk-v0.11-with-go-modules
Updated via: go get github.com/hashicorp/terraform@sdk-v0.11-with-go-modules and go mod tidy
Diffstat (limited to 'vendor/github.com/hashicorp/go-getter/decompress_tar.go')
-rw-r--r--vendor/github.com/hashicorp/go-getter/decompress_tar.go138
1 files changed, 138 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/go-getter/decompress_tar.go b/vendor/github.com/hashicorp/go-getter/decompress_tar.go
new file mode 100644
index 0000000..39cb392
--- /dev/null
+++ b/vendor/github.com/hashicorp/go-getter/decompress_tar.go
@@ -0,0 +1,138 @@
1package getter
2
3import (
4 "archive/tar"
5 "fmt"
6 "io"
7 "os"
8 "path/filepath"
9)
10
11// untar is a shared helper for untarring an archive. The reader should provide
12// an uncompressed view of the tar archive.
13func untar(input io.Reader, dst, src string, dir bool) error {
14 tarR := tar.NewReader(input)
15 done := false
16 dirHdrs := []*tar.Header{}
17 for {
18 hdr, err := tarR.Next()
19 if err == io.EOF {
20 if !done {
21 // Empty archive
22 return fmt.Errorf("empty archive: %s", src)
23 }
24
25 break
26 }
27 if err != nil {
28 return err
29 }
30
31 if hdr.Typeflag == tar.TypeXGlobalHeader || hdr.Typeflag == tar.TypeXHeader {
32 // don't unpack extended headers as files
33 continue
34 }
35
36 path := dst
37 if dir {
38 // Disallow parent traversal
39 if containsDotDot(hdr.Name) {
40 return fmt.Errorf("entry contains '..': %s", hdr.Name)
41 }
42
43 path = filepath.Join(path, hdr.Name)
44 }
45
46 if hdr.FileInfo().IsDir() {
47 if !dir {
48 return fmt.Errorf("expected a single file: %s", src)
49 }
50
51 // A directory, just make the directory and continue unarchiving...
52 if err := os.MkdirAll(path, 0755); err != nil {
53 return err
54 }
55
56 // Record the directory information so that we may set its attributes
57 // after all files have been extracted
58 dirHdrs = append(dirHdrs, hdr)
59
60 continue
61 } else {
62 // There is no ordering guarantee that a file in a directory is
63 // listed before the directory
64 dstPath := filepath.Dir(path)
65
66 // Check that the directory exists, otherwise create it
67 if _, err := os.Stat(dstPath); os.IsNotExist(err) {
68 if err := os.MkdirAll(dstPath, 0755); err != nil {
69 return err
70 }
71 }
72 }
73
74 // We have a file. If we already decoded, then it is an error
75 if !dir && done {
76 return fmt.Errorf("expected a single file, got multiple: %s", src)
77 }
78
79 // Mark that we're done so future in single file mode errors
80 done = true
81
82 // Open the file for writing
83 dstF, err := os.Create(path)
84 if err != nil {
85 return err
86 }
87 _, err = io.Copy(dstF, tarR)
88 dstF.Close()
89 if err != nil {
90 return err
91 }
92
93 // Chmod the file
94 if err := os.Chmod(path, hdr.FileInfo().Mode()); err != nil {
95 return err
96 }
97
98 // Set the access and modification time
99 if err := os.Chtimes(path, hdr.AccessTime, hdr.ModTime); err != nil {
100 return err
101 }
102 }
103
104 // Adding a file or subdirectory changes the mtime of a directory
105 // We therefore wait until we've extracted everything and then set the mtime and atime attributes
106 for _, dirHdr := range dirHdrs {
107 path := filepath.Join(dst, dirHdr.Name)
108 if err := os.Chtimes(path, dirHdr.AccessTime, dirHdr.ModTime); err != nil {
109 return err
110 }
111 }
112
113 return nil
114}
115
116// tarDecompressor is an implementation of Decompressor that can
117// unpack tar files.
118type tarDecompressor struct{}
119
120func (d *tarDecompressor) Decompress(dst, src string, dir bool) error {
121 // If we're going into a directory we should make that first
122 mkdir := dst
123 if !dir {
124 mkdir = filepath.Dir(dst)
125 }
126 if err := os.MkdirAll(mkdir, 0755); err != nil {
127 return err
128 }
129
130 // File first
131 f, err := os.Open(src)
132 if err != nil {
133 return err
134 }
135 defer f.Close()
136
137 return untar(f, dst, src, dir)
138}