github.com/hwaf/hwaf@v0.0.0-20140814122253-5465f73b20f1/utils_tar.go (about)

     1  package main
     2  
     3  import (
     4  	"archive/tar"
     5  	"compress/gzip"
     6  	"fmt"
     7  	"io"
     8  	"os"
     9  	"os/exec"
    10  	"path/filepath"
    11  	"strings"
    12  )
    13  
    14  func _tar_gz(targ, workdir string) error {
    15  
    16  	// FIXME: use archive/tar instead (once go-1.1 is out)
    17  	{
    18  		matches, err := filepath.Glob(filepath.Join(workdir, "*"))
    19  		if err != nil {
    20  			return err
    21  		}
    22  		for i, m := range matches {
    23  			matches[i] = m[len(workdir)+1:]
    24  		}
    25  		args := []string{"-zcf", targ}
    26  		args = append(args, matches...)
    27  		//fmt.Printf(">> %v\n", args)
    28  		cmd := exec.Command("tar", args...)
    29  		cmd.Dir = workdir
    30  		cmd.Stdin = os.Stdin
    31  		cmd.Stdout = os.Stdout
    32  		cmd.Stderr = os.Stderr
    33  		return cmd.Run()
    34  	}
    35  
    36  	f, err := os.Create(targ)
    37  	if err != nil {
    38  		return err
    39  	}
    40  	zout := gzip.NewWriter(f)
    41  	tw := tar.NewWriter(zout)
    42  
    43  	err = filepath.Walk(workdir, func(path string, fi os.FileInfo, err error) error {
    44  		//fmt.Printf("::> [%s]...\n", path)
    45  		if !strings.HasPrefix(path, workdir) {
    46  			err = fmt.Errorf("walked filename %q doesn't begin with workdir %q", path, workdir)
    47  			return err
    48  
    49  		}
    50  		name := path[len(workdir):] //path
    51  
    52  		// make name "relative"
    53  		if strings.HasPrefix(name, "/") {
    54  			name = name[1:]
    55  		}
    56  		target, _ := os.Readlink(path)
    57  		if err != nil {
    58  			return err
    59  		}
    60  		hdr, err := tar.FileInfoHeader(fi, target)
    61  		if err != nil {
    62  			return err
    63  		}
    64  		hdr.Name = name
    65  		hdr.Uname = "root"
    66  		hdr.Gname = "root"
    67  		hdr.Uid = 0
    68  		hdr.Gid = 0
    69  
    70  		// Force permissions to 0755 for executables, 0644 for everything else.
    71  		if fi.Mode().Perm()&0111 != 0 {
    72  			hdr.Mode = hdr.Mode&^0777 | 0755
    73  		} else {
    74  			hdr.Mode = hdr.Mode&^0777 | 0644
    75  		}
    76  
    77  		err = tw.WriteHeader(hdr)
    78  		if err != nil {
    79  			return fmt.Errorf("Error writing file %q: %v", name, err)
    80  		}
    81  		// handle directories and symlinks
    82  		if hdr.Size <= 0 {
    83  			return nil
    84  		}
    85  		r, err := os.Open(path)
    86  		if err != nil {
    87  			return err
    88  		}
    89  		defer r.Close()
    90  		_, err = io.Copy(tw, r)
    91  		return err
    92  	})
    93  	if err != nil {
    94  		return err
    95  	}
    96  	if err := tw.Close(); err != nil {
    97  		return err
    98  	}
    99  	if err := zout.Close(); err != nil {
   100  		return err
   101  	}
   102  	return f.Close()
   103  }
   104  
   105  // EOF