mirror of https://github.com/schollz/croc.git
149 lines
3.1 KiB
Go
149 lines
3.1 KiB
Go
package tarinator
|
|
|
|
import(
|
|
"archive/tar"
|
|
"os"
|
|
"io"
|
|
"log"
|
|
"path/filepath"
|
|
"strings"
|
|
"compress/gzip"
|
|
)
|
|
|
|
func Tarinate(paths []string, tarPath string) error {
|
|
file, err := os.Create(tarPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
var fileReader io.WriteCloser = file
|
|
|
|
if strings.HasSuffix(tarPath, ".gz") {
|
|
fileReader = gzip.NewWriter(file)
|
|
|
|
defer fileReader.Close()
|
|
}
|
|
|
|
tw := tar.NewWriter(fileReader)
|
|
defer tw.Close()
|
|
|
|
for _,i := range paths {
|
|
if err := tarwalk(i, "", tw); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func tarwalk(source, target string, tw *tar.Writer) error {
|
|
info, err := os.Stat(source)
|
|
if err != nil {
|
|
return nil
|
|
}
|
|
|
|
var baseDir string
|
|
if info.IsDir() {
|
|
baseDir = filepath.Base(source)
|
|
}
|
|
|
|
return filepath.Walk(source,
|
|
func(path string, info os.FileInfo, err error) error {
|
|
if err != nil {
|
|
return err
|
|
}
|
|
header, err := tar.FileInfoHeader(info, info.Name())
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if baseDir != "" {
|
|
header.Name = filepath.Join(baseDir, strings.TrimPrefix(path, source))
|
|
}
|
|
|
|
if err := tw.WriteHeader(header); err != nil {
|
|
return err
|
|
}
|
|
|
|
if info.IsDir() {
|
|
return nil
|
|
}
|
|
|
|
if !info.Mode().IsRegular() {
|
|
return nil
|
|
}
|
|
|
|
file, err := os.Open(path)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer file.Close()
|
|
_, err = io.Copy(tw, file)
|
|
return err
|
|
})
|
|
}
|
|
|
|
func UnTarinate(extractPath, sourcefile string) error {
|
|
file, err := os.Open(sourcefile)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
defer file.Close()
|
|
|
|
var fileReader io.ReadCloser = file
|
|
|
|
if strings.HasSuffix(sourcefile, ".gz") {
|
|
if fileReader, err = gzip.NewReader(file); err != nil {
|
|
return err
|
|
}
|
|
defer fileReader.Close()
|
|
}
|
|
|
|
tarBallReader := tar.NewReader(fileReader)
|
|
|
|
for {
|
|
header, err := tarBallReader.Next()
|
|
if err != nil {
|
|
if err == io.EOF {
|
|
break
|
|
}
|
|
return err
|
|
}
|
|
|
|
filename := filepath.Join(extractPath, header.Name)
|
|
|
|
switch header.Typeflag {
|
|
case tar.TypeDir:
|
|
err = os.MkdirAll(filename, os.FileMode(header.Mode)) // or use 0755 if you prefer
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
case tar.TypeReg:
|
|
writer, err := os.Create(filename)
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
io.Copy(writer, tarBallReader)
|
|
|
|
err = os.Chmod(filename, os.FileMode(header.Mode))
|
|
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
writer.Close()
|
|
default:
|
|
log.Printf("Unable to untar type: %c in file %s", header.Typeflag, filename)
|
|
}
|
|
}
|
|
return nil
|
|
}
|