diff --git a/bufferedwriter.go b/bufferedwriter.go new file mode 100644 index 0000000..9209559 --- /dev/null +++ b/bufferedwriter.go @@ -0,0 +1,15 @@ +package squashfs + +import ( + "io" +) + +type bufferedWriter struct { + w io.Writer + buffer []bufferedBytes +} + +type bufferedBytes struct { + data []byte + offset int +} diff --git a/reader.go b/reader.go index 05202f3..120516b 100644 --- a/reader.go +++ b/reader.go @@ -12,7 +12,7 @@ import ( ) const ( - magic = 0x73717368 + magic uint32 = 0x73717368 ) var ( @@ -34,7 +34,7 @@ type Reader struct { fragOffsets []uint64 idTable []uint32 super superblock - flags superblockFlags + flags SuperblockFlags } //NewSquashfsReader returns a new squashfs.Reader from an io.ReaderAt @@ -53,7 +53,7 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) { // return nil, errors.New("BlockSize and BlockLog doesn't match. The archive is probably corrupt") // } rdr.flags = rdr.super.GetFlags() - if rdr.flags.CompressorOptions { + if rdr.flags.compressorOptions { switch rdr.super.CompressionType { case GzipCompression: var gzip *compression.Gzip diff --git a/superblock.go b/superblock.go index ffffc05..8134304 100644 --- a/superblock.go +++ b/superblock.go @@ -33,28 +33,38 @@ type superblock struct { ExportTableStart uint64 } -//SuperblockFlags is the parsed version of Superblock.Flags -type superblockFlags struct { - UncompressedInodes bool - UncompressedData bool - Check bool +//SuperblockFlags is the series of flags describing how a squashfs archive is packed. +type SuperblockFlags struct { + //If true, inodes are stored uncompressed + UncompressedInodes bool + //If true, data is stored uncompressed + UncompressedData bool + check bool + //If true, fragments are stored uncompressed UncompressedFragments bool - NoFragments bool - AlwaysFragments bool - Duplicates bool - Exportable bool - UncompressedXattr bool - NoXattr bool - CompressorOptions bool - UncompressedIDs bool + //If true, ALL data is stored in sequential data blocks instead of utilizing fragments + NoFragments bool + //If true, the last block of data will always be stored as a fragment if it's less then the block size. + AlwaysFragments bool + //If true, duplicate files are only stored once. + Duplicates bool + //If true, the export table is populated + Exportable bool + //If true, the xattr table is uncompressed + UncompressedXattr bool + //If true, the xattr table is not populated + NoXattr bool + compressorOptions bool + //If true, the UID/GID table is stored uncompressed + UncompressedIDs bool } //GetFlags returns a SuperblockFlags for a given superblock. -func (s *superblock) GetFlags() superblockFlags { - return superblockFlags{ +func (s *superblock) GetFlags() SuperblockFlags { + return SuperblockFlags{ UncompressedInodes: s.Flags&0x1 == 0x1, UncompressedData: s.Flags&0x2 == 0x2, - Check: s.Flags&0x4 == 0x4, + check: s.Flags&0x4 == 0x4, UncompressedFragments: s.Flags&0x8 == 0x8, NoFragments: s.Flags&0x10 == 0x10, AlwaysFragments: s.Flags&0x20 == 0x20, @@ -62,7 +72,49 @@ func (s *superblock) GetFlags() superblockFlags { Exportable: s.Flags&0x80 == 0x80, UncompressedXattr: s.Flags&0x100 == 0x100, NoXattr: s.Flags&0x200 == 0x200, - CompressorOptions: s.Flags&0x400 == 0x400, + compressorOptions: s.Flags&0x400 == 0x400, UncompressedIDs: s.Flags&0x800 == 0x800, } } + +//ToUint returns the uint16 representation of the given SuperblockFlags +func (s *SuperblockFlags) ToUint() uint16 { + var out uint16 + if s.UncompressedInodes { + out = out | 0x1 + } + if s.UncompressedData { + out = out | 0x2 + } + if s.check { + out = out | 0x4 + } + if s.UncompressedFragments { + out = out | 0x8 + } + if s.NoFragments { + out = out | 0x10 + } + if s.AlwaysFragments { + out = out | 0x20 + } + if s.Duplicates { + out = out | 0x40 + } + if s.Exportable { + out = out | 0x80 + } + if s.UncompressedXattr { + out = out | 0x100 + } + if s.NoXattr { + out = out | 0x200 + } + if s.compressorOptions { + out = out | 0x400 + } + if s.UncompressedIDs { + out = out | 0x800 + } + return out +} diff --git a/writer.go b/writer.go index 5048bbe..e5ed92c 100644 --- a/writer.go +++ b/writer.go @@ -13,18 +13,6 @@ import ( "github.com/CalebQ42/squashfs/internal/compression" ) -type fileHolder struct { - reader io.Reader - path string - name string - symLocation string - UID int - GUID int - perm int - folder bool - symlink bool -} - //Writer is used to creaste squashfs archives. Currently unusable //TODO: Make usable type Writer struct { @@ -33,8 +21,10 @@ type Writer struct { symlinkTable map[string]string //[oldpath]newpath uidGUIDTable []int compressionType int - Flags superblockFlags - allowErrors bool + //Flags are the SuperblockFlags used when writing the archive. + //Currently Duplicates, Exportable, UncompressedXattr, NoXattr values are ignored + Flags SuperblockFlags + allowErrors bool } //NewWriter creates a new with the default options (Gzip compression and allow errors) @@ -62,6 +52,19 @@ func NewWriterWithOptions(compressionType int, allowErrors bool) (*Writer, error }, nil } +//fileHolder holds the necessary information about a given file inside of a squashfs +type fileHolder struct { + reader io.Reader + path string + name string + symLocation string + UID int + GUID int + perm int + folder bool + symlink bool +} + //AddFile attempts to add an os.File to the archive at it's root. func (w *Writer) AddFile(file *os.File) error { return w.AddFileToFolder("/", file) @@ -318,9 +321,3 @@ func (w *Writer) WriteToFilename(filepath string) error { _, err = w.WriteTo(newFil) return err } - -//WriteTo attempts to write the archive to the given io.Writer. -func (w *Writer) WriteTo(write io.Writer) (int64, error) { - //TODO - return 0, errors.New("I SAID DON'T") -} diff --git a/writer_write.go b/writer_write.go new file mode 100644 index 0000000..2188454 --- /dev/null +++ b/writer_write.go @@ -0,0 +1,12 @@ +package squashfs + +import ( + "errors" + "io" +) + +//WriteTo attempts to write the archive to the given io.Writer. +func (w *Writer) WriteTo(write io.Writer) (int64, error) { + //TODO + return 0, errors.New("I SAID DON'T") +}