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