More work on Writer

This commit is contained in:
Caleb Gardner
2021-01-02 17:10:21 -06:00
parent 162b228881
commit 9524a2c192
3 changed files with 67 additions and 35 deletions
+10 -10
View File
@@ -54,7 +54,7 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
rdr.flags = rdr.super.GetFlags() rdr.flags = rdr.super.GetFlags()
if rdr.flags.CompressorOptions { if rdr.flags.CompressorOptions {
switch rdr.super.CompressionType { switch rdr.super.CompressionType {
case gzipCompression: case GzipCompression:
gzip, err := compression.NewGzipCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 8)) gzip, err := compression.NewGzipCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 8))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -63,7 +63,7 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
hasUnsupportedOptions = true hasUnsupportedOptions = true
} }
rdr.decompressor = gzip rdr.decompressor = gzip
case xzCompression: case XzCompression:
xz, err := compression.NewXzCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 8)) xz, err := compression.NewXzCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 8))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -72,7 +72,7 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
return nil, errors.New("XZ compression options has filters. These are not yet supported") return nil, errors.New("XZ compression options has filters. These are not yet supported")
} }
rdr.decompressor = xz rdr.decompressor = xz
case lz4Compression: case Lz4Compression:
lz4, err := compression.NewLz4CompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 8)) lz4, err := compression.NewLz4CompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 8))
if err != nil { if err != nil {
return nil, err return nil, err
@@ -81,26 +81,26 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
hasUnsupportedOptions = true hasUnsupportedOptions = true
} }
rdr.decompressor = lz4 rdr.decompressor = lz4
case zstdCompression: case ZstdCompression:
zstd, err := compression.NewZstdCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 4)) zstd, err := compression.NewZstdCompressorWithOptions(io.NewSectionReader(rdr.r, int64(binary.Size(rdr.super)), 4))
if err != nil { if err != nil {
return nil, err return nil, err
} }
rdr.decompressor = zstd rdr.decompressor = zstd
default: default:
return nil, errCompressorOptions return nil, errIncompatibleCompression
} }
} else { } else {
switch rdr.super.CompressionType { switch rdr.super.CompressionType {
case gzipCompression: case GzipCompression:
rdr.decompressor = &compression.Gzip{} rdr.decompressor = &compression.Gzip{}
case lzmaCompression: case LzmaCompression:
rdr.decompressor = &compression.Lzma{} rdr.decompressor = &compression.Lzma{}
case xzCompression: case XzCompression:
rdr.decompressor = &compression.Xz{} rdr.decompressor = &compression.Xz{}
case lz4Compression: case Lz4Compression:
rdr.decompressor = &compression.Lz4{} rdr.decompressor = &compression.Lz4{}
case zstdCompression: case ZstdCompression:
rdr.decompressor = &compression.Zstd{} rdr.decompressor = &compression.Zstd{}
default: default:
//TODO: all compression types. //TODO: all compression types.
+7 -6
View File
@@ -1,12 +1,13 @@
package squashfs package squashfs
//The types of compression supported by squashfs.
const ( const (
gzipCompression = 1 + iota GzipCompression = 1 + iota
lzmaCompression LzmaCompression
lzoCompression LzoCompression
xzCompression XzCompression
lz4Compression Lz4Compression
zstdCompression ZstdCompression
) )
//Superblock contains important information about a squashfs file. Located at the very front of the archive. //Superblock contains important information about a squashfs file. Located at the very front of the archive.
+50 -19
View File
@@ -3,36 +3,67 @@ package squashfs
import ( import (
"errors" "errors"
"os" "os"
"path"
"github.com/CalebQ42/squashfs/internal/inode"
) )
//Writer is an interface to write a squashfs. Doesn't write until you call Write (TODO: maybe not do Write...) //Writer is an interface to write a squashfs. Doesn't write until you call Write (TODO: maybe not do Write...)
type Writer struct { type Writer struct {
files map[string]*File files map[string][]*File
directories []string directories []string
resolveSymlinks bool
compression int
temp []*File
} }
func convertFile(file *os.File) (*File, error) { //NewWriter creates a new squashfs.Writer with the default settings (gzip compression and autoresolving symlinks)
func NewWriter() (*Writer, error) {
return NewWriterWithOptions(true, GzipCompression)
}
//NewWriterWithOptions creates a new squashfs.Writer with the given options.
//ResolveSymlinks tries to make sure symlinks aren't broken, and if they would be
func NewWriterWithOptions(resolveSymlinks bool, compressionType int) (*Writer, error) {
if compressionType < 0 || compressionType > 6 || compressionType == 3 {
return nil, errors.New("Incompatible compression type")
}
return &Writer{
files: map[string][]*File{
"/": make([]*File, 0),
},
directories: []string{"/"},
resolveSymlinks: resolveSymlinks,
compression: compressionType,
}, nil
}
func (w *Writer) convertFile(squashfsPath string, file *os.File) error {
var fil File
fil.Reader = file
fil.name = path.Base(file.Name())
fil.path = squashfsPath
stat, err := file.Stat() stat, err := file.Stat()
if err != nil { if err != nil {
return nil, err return err
} }
var filType int defer func() { w.temp = append(w.temp, &fil) }()
if stat.IsDir() { if stat.IsDir() {
//TODO dirs, err := file.Readdirnames(-1)
} else if stat.Mode().IsRegular() { if err != nil {
filType = inode.BasicFileType return err
return &File{ }
Reader: file, for _, dir := range dirs {
name: file.Name(), subFil, err := os.Open(file.Name() + dir)
filType: filType, if err != nil {
}, nil return err
} else if stat.Mode()&os.ModeSymlink == os.ModeSymlink { }
//TODO: implement symlink support err = w.convertFile(fil.Path(), subFil)
return nil, errors.New("No symlink support. No support at all actually...") if err != nil {
return err
}
}
} }
return nil, errors.New("File type is NOT supported") //TODO: reg files & symlinks
return nil
} }
//AddFilesToPath adds the give os.Files to the given path within the squashfs archive. //AddFilesToPath adds the give os.Files to the given path within the squashfs archive.