Skip to content

Instantly share code, notes, and snippets.

@grimpy
Created June 8, 2020 09:30
Show Gist options
  • Save grimpy/e68c6add168e9e20101b7b74416e6eb8 to your computer and use it in GitHub Desktop.
Save grimpy/e68c6add168e9e20101b7b74416e6eb8 to your computer and use it in GitHub Desktop.
package main
import (
"archive/tar"
"compress/gzip"
"flag"
"io"
"path"
"log"
"os"
"fmt"
)
const uploadbloks int64 = 100 * 1024 * 1024
func isEmptyBuffer(buf []byte) bool {
for _, b := range buf {
if b != '\x00' {
return false
}
}
return true
}
// shamelessly copied from io.copybuffer and adapted to skip zero writes
func copy(src io.Reader, dst *os.File) (written int64, err error) {
buf := make([]byte, 1024*4)
var seek int64
for {
nr, er := src.Read(buf)
if nr > 0 {
if isEmptyBuffer(buf[0:nr]) {
seek += int64(nr)
continue
}
if seek != 0 {
_, err := dst.Seek(seek, 1)
if err != nil {
return 0, err
}
seek = 0
}
nw, ew := dst.Write(buf[0:nr])
if nw > 0 {
written += int64(nw)
}
if ew != nil {
err = ew
break
}
if nr != nw {
err = io.ErrShortWrite
break
}
}
if er != nil {
if er != io.EOF {
err = er
}
break
}
}
return
}
func writeFile(filepath string, size int64, reader *tar.Reader) error {
file, err := os.OpenFile(filepath, os.O_RDWR | os.O_CREATE, 0666)
if err != nil {
return err
}
file.Truncate(size)
defer file.Close()
datawritten, err := copy(reader, file)
if err != nil {
return err
}
file.Sync()
log.Printf("Written %d data", datawritten)
return nil
}
func writeFiles(reader io.Reader) error {
gzipreader, err := gzip.NewReader(reader)
if err != nil {
return err
}
tarreader := tar.NewReader(gzipreader)
for {
hdr, err := tarreader.Next()
if err == io.EOF {
break
}
if err != nil {
return err
}
log.Printf("Extracting %s", hdr.Name)
err = writeFile(path.Base(hdr.Name), hdr.Size, tarreader)
if err != nil {
return err
}
}
return nil
}
func main() {
var file string
flag.StringVar(&file, "file", "", "File to extract")
flag.Parse()
var reader io.ReadCloser
if file == "-" {
reader, _ = os.Open("/dev/stdin")
} else {
reader, _ = os.Open(file)
}
defer reader.Close()
err := writeFiles(reader)
if err != nil {
fmt.Print(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment