mirror of
https://github.com/vbatts/tar-split.git
synced 2024-12-24 06:16:31 +00:00
tar/asm: add FileGetter and concerns in README
This commit is contained in:
parent
7ccbb9d40c
commit
e1206b43a6
3 changed files with 52 additions and 22 deletions
|
@ -5,6 +5,21 @@ This library for assembly and disassembly of tar archives, facilitated by
|
||||||
`github.com/vbatts/tar-split/tar/storage`.
|
`github.com/vbatts/tar-split/tar/storage`.
|
||||||
|
|
||||||
|
|
||||||
|
Concerns
|
||||||
|
--------
|
||||||
|
|
||||||
|
For completely safe assembly/disassembly, there will need to be a CAS
|
||||||
|
directory, that maps to a checksum in the `storage.Entity` of
|
||||||
|
`storage.FileType`.
|
||||||
|
|
||||||
|
This is due to the fact that tar archives _can_ allow multiple records for the
|
||||||
|
same path, but the last one effectively wins. Even if the prior records had a
|
||||||
|
different payload.
|
||||||
|
|
||||||
|
In this way, when assembling an archive from relative paths, if the archive has
|
||||||
|
multiple entries for the same path, then all payloads read in from a relative
|
||||||
|
path would be identical.
|
||||||
|
|
||||||
|
|
||||||
Thoughts
|
Thoughts
|
||||||
--------
|
--------
|
||||||
|
|
|
@ -2,13 +2,11 @@ package asm
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
|
|
||||||
"github.com/vbatts/tar-split/tar/storage"
|
"github.com/vbatts/tar-split/tar/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
func NewTarStream(relpath string, up storage.Unpacker) io.ReadCloser {
|
func NewTarStream(fg FileGetter, up storage.Unpacker) io.ReadCloser {
|
||||||
pr, pw := io.Pipe()
|
pr, pw := io.Pipe()
|
||||||
go func() {
|
go func() {
|
||||||
for {
|
for {
|
||||||
|
@ -24,7 +22,16 @@ func NewTarStream(relpath string, up storage.Unpacker) io.ReadCloser {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
case storage.FileType:
|
case storage.FileType:
|
||||||
if err := writeEntryFromRelPath(pw, relpath, entry); err != nil {
|
if entry.Size == 0 {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
fh, err := fg.Get(entry.Name)
|
||||||
|
if err != nil {
|
||||||
|
pw.CloseWithError(err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
defer fh.Close()
|
||||||
|
if _, err := io.Copy(pw, fh); err != nil {
|
||||||
pw.CloseWithError(err)
|
pw.CloseWithError(err)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
@ -33,21 +40,3 @@ func NewTarStream(relpath string, up storage.Unpacker) io.ReadCloser {
|
||||||
}()
|
}()
|
||||||
return pr
|
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
|
|
||||||
}
|
|
||||||
|
|
26
tar/asm/getter.go
Normal file
26
tar/asm/getter.go
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
package asm
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
)
|
||||||
|
|
||||||
|
type FileGetter interface {
|
||||||
|
// Get returns a stream for the provided file path
|
||||||
|
Get(string) (io.ReadCloser, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewPathFileGetter returns a FileGetter that is for files relative to path relpath.
|
||||||
|
func NewPathFileGetter(relpath string) FileGetter {
|
||||||
|
return &pathFileGetter{root: relpath}
|
||||||
|
}
|
||||||
|
|
||||||
|
type pathFileGetter struct {
|
||||||
|
root string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (pfg pathFileGetter) Get(filename string) (io.ReadCloser, error) {
|
||||||
|
// FIXME might should have a check for '../../../../etc/passwd' attempts?
|
||||||
|
return os.Open(path.Join(pfg.root, filename))
|
||||||
|
}
|
Loading…
Reference in a new issue