From 07962426b2128202b111299b7ee7304c01c6426f Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Wed, 3 Feb 2021 14:03:21 -0600 Subject: [PATCH] Minor work on the Writer --- writer.go | 26 ++++++++++++++++++++------ writer_write.go | 22 +++++++++++++++++++--- 2 files changed, 39 insertions(+), 9 deletions(-) diff --git a/writer.go b/writer.go index 6521210..ec70b0c 100644 --- a/writer.go +++ b/writer.go @@ -19,6 +19,7 @@ type Writer struct { compressor compression.Compressor structure map[string][]*fileHolder symlinkTable map[string]string //[oldpath]newpath + folders []string uidGUIDTable []int compressionType int //BlockSize is how large the data blocks are. Can be between 4096 (4KB) and 1048576 (1 MB). @@ -44,12 +45,15 @@ func NewWriterWithOptions(compressionType int, allowErrors bool) (*Writer, error return nil, errors.New("Incorrect compression type") } if compressionType == 3 { - return nil, errors.New("LZO compression is not (currently) supported") + return nil, errors.New("Lzo compression is not (currently) supported") } return &Writer{ structure: map[string][]*fileHolder{ "/": make([]*fileHolder, 0), }, + folders: []string{ + "/", + }, symlinkTable: make(map[string]string), compressionType: compressionType, allowErrors: allowErrors, @@ -71,7 +75,7 @@ type fileHolder struct { symlink bool } -//AddFile attempts to add an os.File to the archive at it's root. +//AddFile attempts to add an os.File to the archive's root directory. func (w *Writer) AddFile(file *os.File) error { return w.AddFileToFolder("/", file) } @@ -95,8 +99,7 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error { return errors.New("File already exists at " + filepath) } var holder fileHolder - holder.path, holder.name = path.Split(filepath) - holder.reader = file + holder.path, holder.name = path.Dir(filepath), path.Base(filepath) stat, err := file.Stat() if err != nil { return err @@ -118,6 +121,7 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error { sort.Ints(w.uidGUIDTable) } if holder.symlink { + holder.reader = file target, err := os.Readlink(file.Name()) if err != nil { return err @@ -148,9 +152,15 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error { dirsAdded = append(dirsAdded, holder.path+"/"+holder.name) } } - } else if !stat.Mode().IsRegular() { + } else if stat.Mode().IsRegular() { + holder.reader = file + } else { return errors.New("Unsupported file type " + file.Name()) } + if _, ok := w.structure[holder.path]; ok { + w.folders = append(w.folders, holder.path) + sort.Strings(w.folders) + } w.structure[holder.path] = append(w.structure[holder.path], &holder) return nil } @@ -167,8 +177,12 @@ func (w *Writer) AddReaderTo(filepath string, reader io.Reader) error { return errors.New("File already exists at " + filepath) } var holder fileHolder - holder.path, holder.name = path.Split(filepath) + holder.path, holder.name = path.Dir(filepath), path.Base(filepath) holder.reader = reader + if _, ok := w.structure[holder.path]; ok { + w.folders = append(w.folders, holder.path) + sort.Strings(w.folders) + } w.structure[holder.path] = append(w.structure[holder.path], &holder) return nil } diff --git a/writer_write.go b/writer_write.go index 0ee8bab..9cbe922 100644 --- a/writer_write.go +++ b/writer_write.go @@ -4,25 +4,41 @@ import ( "errors" "io" "math" + "time" ) +func (w Writer) countInodes() (out uint32) { + out++ // for the root indode + for _, fold := range w.folders { + out += uint32(len(w.structure[fold])) + } + return +} + //WriteTo attempts to write the archive to the given io.Writer. -func (w *Writer) WriteTo(write io.Writer) (int64, error) { +func (w *Writer) WriteTo(write io.WriteSeeker) (int64, error) { if w.BlockSize > 1048576 { w.BlockSize = 1048576 } else if w.BlockSize < 4096 { w.BlockSize = 4096 } + w.Flags.Duplicates = false + w.Flags.Exportable = false + w.Flags.NoXattr = true //TODO: set forced Flag values - _ = superblock{ + //TODO: make sure we aren't missing folders + super := superblock{ Magic: magic, + InodeCount: w.countInodes(), + CreationTime: uint32(time.Now().Unix()), BlockSize: w.BlockSize, - BlockLog: uint16(math.Log2(float64(w.BlockSize))), CompressionType: uint16(w.compressionType), + BlockLog: uint16(math.Log2(float64(w.BlockSize))), Flags: w.Flags.ToUint(), IDCount: uint16(len(w.uidGUIDTable)), MajorVersion: 4, MinorVersion: 0, } + _ = super return 0, errors.New("I SAID DON'T") }