| // Copyright 2019 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| package util |
| |
| import ( |
| "archive/tar" |
| "bytes" |
| "compress/gzip" |
| "io" |
| "log" |
| "os" |
| "os/exec" |
| "path/filepath" |
| ) |
| |
| // RunCommand executes a command on the host and returns the stdout and stderr |
| // as byte strings. |
| func RunCommand(name string, arg ...string) ([]byte, []byte, error) { |
| log.Printf("running: %s %q", name, arg) |
| c := exec.Command(name, arg...) |
| var o bytes.Buffer |
| var e bytes.Buffer |
| c.Stdout = &o |
| c.Stderr = &e |
| err := c.Run() |
| stdout := o.Bytes() |
| stderr := e.Bytes() |
| return stdout, stderr, err |
| } |
| |
| // Untar untars a tar.gz file into a directory. |
| func Untar(dst string, src string) error { |
| log.Printf("untarring %s into %s", src, dst) |
| |
| f, err := os.Open(src) |
| if err != nil { |
| return err |
| } |
| defer f.Close() |
| |
| gz, err := gzip.NewReader(f) |
| if err != nil { |
| return err |
| } |
| defer gz.Close() |
| |
| tr := tar.NewReader(gz) |
| |
| for { |
| header, err := tr.Next() |
| if err == io.EOF { |
| return nil |
| } else if err != nil { |
| return err |
| } |
| |
| path := filepath.Join(dst, header.Name) |
| info := header.FileInfo() |
| if info.IsDir() { |
| if err := os.MkdirAll(path, info.Mode()); err != nil { |
| return err |
| } |
| } else { |
| if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil { |
| return err |
| } |
| |
| f, err := os.OpenFile(path, os.O_CREATE|os.O_EXCL|os.O_WRONLY, info.Mode()) |
| if err != nil { |
| return err |
| } |
| |
| if _, err := io.Copy(f, tr); err != nil { |
| f.Close() |
| return err |
| } |
| |
| f.Close() |
| } |
| } |
| } |