1
0
Fork 1
mirror of https://github.com/vbatts/tar-split.git synced 2024-12-18 19:46:29 +00:00

tar/asm: initial assmebly of tar stream

This commit is contained in:
Vincent Batts 2015-02-24 17:07:00 -05:00
parent 34a67dfed5
commit 7ccbb9d40c
2 changed files with 71 additions and 0 deletions

18
tar/asm/README.md Normal file
View file

@ -0,0 +1,18 @@
asm
===
This library for assembly and disassembly of tar archives, facilitated by
`github.com/vbatts/tar-split/tar/storage`.
Thoughts
--------
While the initial implementation is based on a relative path, I'm thinking the
next step is to have something like a FileGetter interface, of which a path
based getter is just one type.
Then you could pass a path based Getter and an Unpacker, and receive a
io.Reader that is your tar stream.

53
tar/asm/assemble.go Normal file
View file

@ -0,0 +1,53 @@
package asm
import (
"io"
"os"
"path"
"github.com/vbatts/tar-split/tar/storage"
)
func NewTarStream(relpath string, up storage.Unpacker) io.ReadCloser {
pr, pw := io.Pipe()
go func() {
for {
entry, err := up.Next()
if err != nil {
pw.CloseWithError(err)
break
}
switch entry.Type {
case storage.SegmentType:
if _, err := pw.Write(entry.Payload); err != nil {
pw.CloseWithError(err)
break
}
case storage.FileType:
if err := writeEntryFromRelPath(pw, relpath, entry); err != nil {
pw.CloseWithError(err)
break
}
}
}
}()
return pr
}
func writeEntryFromRelPath(w io.Writer, root string, entry *storage.Entry) error {
if entry.Size == 0 {
return nil
}
// FIXME might should have a check for '../../../../etc/passwd' attempts?
fh, err := os.Open(path.Join(root, entry.Name))
if err != nil {
return err
}
defer fh.Close()
if _, err := io.Copy(w, fh); err != nil {
return err
}
return nil
}