Getting back into it...
This commit is contained in:
+18
-12
@@ -35,30 +35,36 @@ type superblock struct {
|
|||||||
|
|
||||||
//SuperblockFlags is the series of flags describing how a squashfs archive is packed.
|
//SuperblockFlags is the series of flags describing how a squashfs archive is packed.
|
||||||
type SuperblockFlags struct {
|
type SuperblockFlags struct {
|
||||||
//If true, inodes are stored uncompressed
|
//If true, inodes are stored uncompressed.
|
||||||
UncompressedInodes bool
|
UncompressedInodes bool
|
||||||
//If true, data is stored uncompressed
|
//If true, data is stored uncompressed.
|
||||||
UncompressedData bool
|
UncompressedData bool
|
||||||
check bool
|
check bool
|
||||||
//If true, fragments are stored uncompressed
|
//If true, fragments are stored uncompressed.
|
||||||
UncompressedFragments bool
|
UncompressedFragments bool
|
||||||
//If true, ALL data is stored in sequential data blocks instead of utilizing fragments
|
//If true, ALL data is stored in sequential data blocks instead of utilizing fragments.
|
||||||
NoFragments bool
|
NoFragments bool
|
||||||
//If true, the last block of data will always be stored as a fragment if it's less then the block size.
|
//If true, the last block of data will always be stored as a fragment if it's less then the block size.
|
||||||
AlwaysFragments bool
|
AlwaysFragments bool
|
||||||
//If true, duplicate files are only stored once.
|
//If true, duplicate files are only stored once. (Currently unsupported)
|
||||||
Duplicates bool
|
RemoveDuplicates bool
|
||||||
//If true, the export table is populated
|
//If true, the export table is populated. (Currently unsupported)
|
||||||
Exportable bool
|
Exportable bool
|
||||||
//If true, the xattr table is uncompressed
|
//If true, the xattr table is uncompressed. (Currently unsupported)
|
||||||
UncompressedXattr bool
|
UncompressedXattr bool
|
||||||
//If true, the xattr table is not populated
|
//If true, the xattr table is not populated. (Currently unsupported)
|
||||||
NoXattr bool
|
NoXattr bool
|
||||||
compressorOptions bool
|
compressorOptions bool
|
||||||
//If true, the UID/GID table is stored uncompressed
|
//If true, the UID/GID table is stored uncompressed.
|
||||||
UncompressedIDs bool
|
UncompressedIDs bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//DefaultFlags are the default SuperblockFlags that are used.
|
||||||
|
var DefaultFlags = SuperblockFlags{
|
||||||
|
RemoveDuplicates: true,
|
||||||
|
Exportable: true,
|
||||||
|
}
|
||||||
|
|
||||||
//GetFlags returns a SuperblockFlags for a given superblock.
|
//GetFlags returns a SuperblockFlags for a given superblock.
|
||||||
func (s *superblock) GetFlags() SuperblockFlags {
|
func (s *superblock) GetFlags() SuperblockFlags {
|
||||||
return SuperblockFlags{
|
return SuperblockFlags{
|
||||||
@@ -68,7 +74,7 @@ func (s *superblock) GetFlags() SuperblockFlags {
|
|||||||
UncompressedFragments: s.Flags&0x8 == 0x8,
|
UncompressedFragments: s.Flags&0x8 == 0x8,
|
||||||
NoFragments: s.Flags&0x10 == 0x10,
|
NoFragments: s.Flags&0x10 == 0x10,
|
||||||
AlwaysFragments: s.Flags&0x20 == 0x20,
|
AlwaysFragments: s.Flags&0x20 == 0x20,
|
||||||
Duplicates: s.Flags&0x40 == 0x40,
|
RemoveDuplicates: s.Flags&0x40 == 0x40,
|
||||||
Exportable: s.Flags&0x80 == 0x80,
|
Exportable: s.Flags&0x80 == 0x80,
|
||||||
UncompressedXattr: s.Flags&0x100 == 0x100,
|
UncompressedXattr: s.Flags&0x100 == 0x100,
|
||||||
NoXattr: s.Flags&0x200 == 0x200,
|
NoXattr: s.Flags&0x200 == 0x200,
|
||||||
@@ -98,7 +104,7 @@ func (s *SuperblockFlags) ToUint() uint16 {
|
|||||||
if s.AlwaysFragments {
|
if s.AlwaysFragments {
|
||||||
out = out | 0x20
|
out = out | 0x20
|
||||||
}
|
}
|
||||||
if s.Duplicates {
|
if s.RemoveDuplicates {
|
||||||
out = out | 0x40
|
out = out | 0x40
|
||||||
}
|
}
|
||||||
if s.Exportable {
|
if s.Exportable {
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package squashfs
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
|
"io/fs"
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
@@ -29,6 +30,9 @@ type Writer struct {
|
|||||||
//Currently Duplicates, Exportable, UncompressedXattr, NoXattr values are ignored
|
//Currently Duplicates, Exportable, UncompressedXattr, NoXattr values are ignored
|
||||||
Flags SuperblockFlags
|
Flags SuperblockFlags
|
||||||
allowErrors bool
|
allowErrors bool
|
||||||
|
|
||||||
|
//variables used when actually writing.
|
||||||
|
superblock superblock
|
||||||
}
|
}
|
||||||
|
|
||||||
//NewWriter creates a new with the default options (Gzip compression and allow errors)
|
//NewWriter creates a new with the default options (Gzip compression and allow errors)
|
||||||
@@ -54,6 +58,7 @@ func NewWriterWithOptions(compressionType int, allowErrors bool) (*Writer, error
|
|||||||
compressionType: compressionType,
|
compressionType: compressionType,
|
||||||
allowErrors: allowErrors,
|
allowErrors: allowErrors,
|
||||||
BlockSize: uint32(1048576),
|
BlockSize: uint32(1048576),
|
||||||
|
Flags: DefaultFlags,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,7 +100,8 @@ func (w *Writer) AddFileTo(filepath string, file *os.File) error {
|
|||||||
return errors.New("File already exists at " + filepath)
|
return errors.New("File already exists at " + filepath)
|
||||||
}
|
}
|
||||||
var holder fileHolder
|
var holder fileHolder
|
||||||
holder.path, holder.name = path.Split(filepath)
|
holder.path = path.Dir(filepath)
|
||||||
|
holder.name = path.Base(filepath)
|
||||||
holder.reader = file
|
holder.reader = file
|
||||||
stat, err := file.Stat()
|
stat, err := file.Stat()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -167,12 +173,35 @@ func (w *Writer) AddReaderTo(filepath string, reader io.Reader) error {
|
|||||||
return errors.New("File already exists at " + filepath)
|
return errors.New("File already exists at " + filepath)
|
||||||
}
|
}
|
||||||
var holder fileHolder
|
var holder fileHolder
|
||||||
holder.path, holder.name = path.Split(filepath)
|
holder.path = path.Dir(filepath)
|
||||||
|
holder.name = path.Base(filepath)
|
||||||
holder.reader = reader
|
holder.reader = reader
|
||||||
w.structure[holder.path] = append(w.structure[holder.path], &holder)
|
w.structure[holder.path] = append(w.structure[holder.path], &holder)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//AddFolderTo adds a folder at the given path. IF the folder is already present, it sets the folder's permissions.
|
||||||
|
//If the path points to a non-folder (such as a file or symlink), an error is returned
|
||||||
|
func (w *Writer) AddFolderTo(folderpath string, permission fs.FileMode) error {
|
||||||
|
folderpath = path.Clean(folderpath)
|
||||||
|
tmp := w.holderAt(folderpath)
|
||||||
|
if tmp != nil {
|
||||||
|
if !tmp.folder {
|
||||||
|
return errors.New("Path is not a folder: " + folderpath)
|
||||||
|
}
|
||||||
|
tmp.perm = int(permission.Perm())
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
file := fileHolder{
|
||||||
|
path: path.Dir(folderpath),
|
||||||
|
name: path.Base(folderpath),
|
||||||
|
perm: int(permission | fs.ModePerm),
|
||||||
|
folder: true,
|
||||||
|
}
|
||||||
|
w.structure[file.path] = append(w.structure[file.path], &file)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//Remove tries to remove the file(s) at the given filepath. If wildcards are used, it will remove all files that match.
|
//Remove tries to remove the file(s) at the given filepath. If wildcards are used, it will remove all files that match.
|
||||||
//Returns true if one or more files are removed.
|
//Returns true if one or more files are removed.
|
||||||
func (w *Writer) Remove(filepath string) bool {
|
func (w *Writer) Remove(filepath string) bool {
|
||||||
|
|||||||
+14
-2
@@ -4,8 +4,18 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
|
"path"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (w *Writer) fixFolders() error {
|
||||||
|
for folder := range w.structure {
|
||||||
|
if folder == "/" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
dir, name := path.Dir(folder), path.Base(folder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
//WriteTo attempts to write the archive to the given io.Writer.
|
//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.Writer) (int64, error) {
|
||||||
if w.BlockSize > 1048576 {
|
if w.BlockSize > 1048576 {
|
||||||
@@ -13,8 +23,10 @@ func (w *Writer) WriteTo(write io.Writer) (int64, error) {
|
|||||||
} else if w.BlockSize < 4096 {
|
} else if w.BlockSize < 4096 {
|
||||||
w.BlockSize = 4096
|
w.BlockSize = 4096
|
||||||
}
|
}
|
||||||
//TODO: set forced Flag values
|
w.Flags.RemoveDuplicates = false
|
||||||
_ = superblock{
|
w.Flags.Exportable = false
|
||||||
|
w.Flags.NoXattr = true
|
||||||
|
w.superblock = superblock{
|
||||||
Magic: magic,
|
Magic: magic,
|
||||||
BlockSize: w.BlockSize,
|
BlockSize: w.BlockSize,
|
||||||
BlockLog: uint16(math.Log2(float64(w.BlockSize))),
|
BlockLog: uint16(math.Log2(float64(w.BlockSize))),
|
||||||
|
|||||||
Reference in New Issue
Block a user