More work on Writer
This commit is contained in:
@@ -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
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
Reference in New Issue
Block a user