diff --git a/compression.go b/compression.go index a97e05e..72eccbb 100644 --- a/compression.go +++ b/compression.go @@ -7,15 +7,15 @@ import ( ) //Decompressor is a squashfs decompressor interface. Allows for easy decompression no matter the type of compression. -type Decompressor interface { +type decompressor interface { Decompress(io.Reader) ([]byte, error) } //ZlibDecompressor is a decompressor for gzip type compression -type ZlibDecompressor struct{} +type zlibDecompressor struct{} //Decompress reads the entirety of the given reader and returns it uncompressed as a byte slice. -func (z *ZlibDecompressor) Decompress(r io.Reader) ([]byte, error) { +func (z *zlibDecompressor) Decompress(r io.Reader) ([]byte, error) { rdr, err := zlib.NewReader(r) if err != nil { return nil, err diff --git a/datareader.go b/datareader.go index 94c4eb5..644c0b2 100644 --- a/datareader.go +++ b/datareader.go @@ -3,7 +3,6 @@ package squashfs import ( "bytes" "errors" - "fmt" "io" "github.com/CalebQ42/GoSquashfs/internal/inode" @@ -17,17 +16,17 @@ var ( ) //DataReader reads data from data blocks. -type DataReader struct { +type dataReader struct { r *Reader offset int64 //offset relative to the beginning of the squash file - blocks []DataBlock + blocks []dataBlock curBlock int //Which block in sizes is currently cached curData []byte curReadOffset int //offset relative to the currently cached data } //DataBlock holds info about a given data block from it's size -type DataBlock struct { +type dataBlock struct { begOffset int64 //The offset relative to the beginning of the squash file. Makes it easier to seek to it. size uint32 compressed bool @@ -35,7 +34,7 @@ type DataBlock struct { } //NewDataBlock creates a new squashfs.datablock from a given size. -func NewDataBlock(raw uint32) (dbs DataBlock) { +func newDataBlock(raw uint32) (dbs dataBlock) { dbs.compressed = raw&(1<<24) != (1 << 24) dbs.size = raw &^ (1 << 24) if !dbs.compressed { @@ -45,12 +44,12 @@ func NewDataBlock(raw uint32) (dbs DataBlock) { } //NewDataReader creates a new data reader at the given offset, with the blocks defined by sizes -func (r *Reader) NewDataReader(offset int64, sizes []uint32) (*DataReader, error) { - var dr DataReader +func (r *Reader) newDataReader(offset int64, sizes []uint32) (*dataReader, error) { + var dr dataReader dr.r = r dr.offset = offset for _, size := range sizes { - dr.blocks = append(dr.blocks, NewDataBlock(size)) + dr.blocks = append(dr.blocks, newDataBlock(size)) } err := dr.readCurBlock() if err != nil { @@ -60,8 +59,8 @@ func (r *Reader) NewDataReader(offset int64, sizes []uint32) (*DataReader, error } //NewDataReaderFromInode creates a new DataReader from a given inode. Inode must be of BasicFile or ExtendedFile types -func (r *Reader) NewDataReaderFromInode(i *inode.Inode) (*DataReader, error) { - var rdr DataReader +func (r *Reader) newDataReaderFromInode(i *inode.Inode) (*dataReader, error) { + var rdr dataReader rdr.r = r switch i.Type { case inode.BasicFileType: @@ -71,7 +70,7 @@ func (r *Reader) NewDataReaderFromInode(i *inode.Inode) (*DataReader, error) { } rdr.offset = int64(fil.Init.BlockStart) for _, sizes := range fil.BlockSizes { - rdr.blocks = append(rdr.blocks, NewDataBlock(sizes)) + rdr.blocks = append(rdr.blocks, newDataBlock(sizes)) } if fil.Fragmented { rdr.blocks = rdr.blocks[:len(rdr.blocks)-1] @@ -83,7 +82,7 @@ func (r *Reader) NewDataReaderFromInode(i *inode.Inode) (*DataReader, error) { } rdr.offset = int64(fil.Init.BlockStart) for _, sizes := range fil.BlockSizes { - rdr.blocks = append(rdr.blocks, NewDataBlock(sizes)) + rdr.blocks = append(rdr.blocks, newDataBlock(sizes)) } if fil.Fragmented { rdr.blocks = rdr.blocks[:len(rdr.blocks)-1] @@ -98,7 +97,7 @@ func (r *Reader) NewDataReaderFromInode(i *inode.Inode) (*DataReader, error) { return &rdr, nil } -func (d *DataReader) readNextBlock() error { +func (d *dataReader) readNextBlock() error { d.curBlock++ if d.curBlock >= len(d.blocks) { d.curBlock-- @@ -108,15 +107,12 @@ func (d *DataReader) readNextBlock() error { if err != nil { d.curBlock-- d.readCurBlock() - fmt.Println("running back because of issues") return err } - fmt.Println("Read block success!") return nil } -func (d *DataReader) readCurBlock() error { - fmt.Println("reading into block", d.curBlock, "out of", len(d.blocks)) +func (d *dataReader) readCurBlock() error { if d.curBlock >= len(d.blocks) { return io.EOF } @@ -127,12 +123,9 @@ func (d *DataReader) readCurBlock() error { return nil } sec := io.NewSectionReader(d.r.r, d.offset, int64(d.blocks[d.curBlock].size)) - fmt.Println("block size", d.r.super.BlockSize) - fmt.Println("compressed size", int64(d.blocks[d.curBlock].size)) if d.blocks[d.curBlock].compressed { btys, err := d.r.decompressor.Decompress(sec) if err != nil { - fmt.Println("HERE!") return err } d.blocks[d.curBlock].uncompressedSize = uint32(len(btys)) @@ -152,9 +145,8 @@ func (d *DataReader) readCurBlock() error { return err } -func (d *DataReader) Read(p []byte) (int, error) { +func (d *dataReader) Read(p []byte) (int, error) { if d.curReadOffset+len(p) < len(d.curData) { - fmt.Println("Enough data in cache for direct read") for i := 0; i < len(p); i++ { p[i] = d.curData[d.curReadOffset+i] } @@ -164,7 +156,6 @@ func (d *DataReader) Read(p []byte) (int, error) { read := 0 for read < len(p) { if d.curReadOffset == len(d.curData) { - fmt.Println("reading new block...") err := d.readNextBlock() if err != nil { return read, err @@ -176,7 +167,6 @@ func (d *DataReader) Read(p []byte) (int, error) { if d.curReadOffset < len(d.curData) { p[read] = d.curData[d.curReadOffset] } else { - fmt.Println("breaking out!") break } } diff --git a/filereader.go b/filereader.go index 76eeb53..a624fe2 100644 --- a/filereader.go +++ b/filereader.go @@ -3,16 +3,15 @@ package squashfs import ( "bytes" "errors" - "fmt" "io" "github.com/CalebQ42/GoSquashfs/internal/inode" ) -//FileReader provides a io.Reader interface for files within +//FileReader provides a io.Reader interface for files within a squashfs archive type FileReader struct { r *Reader - data *DataReader + data *dataReader fragmentData []byte fragged bool fragOnly bool @@ -49,21 +48,19 @@ func (r *Reader) ReadFile(location string) (*FileReader, error) { rdr.FileSize = int(fil.Init.Size) } if rdr.fragged { - rdr.fragmentData, err = r.GetFragmentDataFromInode(in) + rdr.fragmentData, err = r.getFragmentDataFromInode(in) if err != nil { return nil, err } } if !rdr.fragOnly { - rdr.data, err = r.NewDataReaderFromInode(in) + rdr.data, err = r.newDataReaderFromInode(in) } return &rdr, nil } func (f *FileReader) Read(p []byte) (int, error) { - fmt.Println("reading!", len(p)) if f.fragOnly { - fmt.Println("HII") n, err := bytes.NewBuffer(f.fragmentData[f.read:]).Read(p) f.read += n if err != nil { @@ -75,7 +72,6 @@ func (f *FileReader) Read(p []byte) (int, error) { n, err := f.data.Read(p) read += n if f.fragged && err == io.EOF { - fmt.Println("Trying to read fragment AFTER main data") n, err = bytes.NewBuffer(f.fragmentData).Read(p[read:]) read += n if err != nil { @@ -84,6 +80,5 @@ func (f *FileReader) Read(p []byte) (int, error) { } else if err != nil { return read, err } - fmt.Println("read", n) return read, nil } diff --git a/fragment.go b/fragment.go index d42e6b8..5909d1c 100644 --- a/fragment.go +++ b/fragment.go @@ -3,7 +3,6 @@ package squashfs import ( "encoding/binary" "errors" - "fmt" "io" "github.com/CalebQ42/GoSquashfs/internal/inode" @@ -18,7 +17,7 @@ type FragmentEntry struct { //GetFragmentDataFromInode returns the fragment data for a given inode. //If the inode does not have a fragment, harmlessly returns an empty slice without an error. -func (r *Reader) GetFragmentDataFromInode(in *inode.Inode) ([]byte, error) { +func (r *Reader) getFragmentDataFromInode(in *inode.Inode) ([]byte, error) { var size uint32 var fragIndex uint32 var fragOffset uint32 @@ -50,7 +49,7 @@ func (r *Reader) GetFragmentDataFromInode(in *inode.Inode) ([]byte, error) { return nil, errors.New("Inode type not supported") } //reading the fragment entry first - fragEntryRdr, err := r.NewMetadataReader(int64(r.fragOffsets[int(fragIndex/512)])) + fragEntryRdr, err := r.newMetadataReader(int64(r.fragOffsets[int(fragIndex/512)])) if err != nil { return nil, err } @@ -64,7 +63,7 @@ func (r *Reader) GetFragmentDataFromInode(in *inode.Inode) ([]byte, error) { return nil, err } //now reading the actual fragment - dr, err := r.NewDataReader(int64(entry.Start), []uint32{entry.Size}) + dr, err := r.newDataReader(int64(entry.Start), []uint32{entry.Size}) if err != nil { return nil, err } @@ -77,6 +76,5 @@ func (r *Reader) GetFragmentDataFromInode(in *inode.Inode) ([]byte, error) { if err != nil { return nil, err } - fmt.Println("read fragment with size", len(tmp)) return tmp, nil } diff --git a/metadatareader.go b/metadatareader.go index 061b5b9..5c6261a 100644 --- a/metadatareader.go +++ b/metadatareader.go @@ -14,7 +14,7 @@ type metadata struct { } //MetadataReader is a block reader for metadata. It will automatically read the next block, when it reaches the end of a block. -type MetadataReader struct { +type metadataReader struct { s *Reader offset int64 headers []*metadata @@ -23,8 +23,8 @@ type MetadataReader struct { } //NewMetadataReader creates a new MetadataReader, beginning to read at the given offset. It will automatically cache the first block at the location. -func (s *Reader) NewMetadataReader(offset int64) (*MetadataReader, error) { - var br MetadataReader +func (s *Reader) newMetadataReader(offset int64) (*metadataReader, error) { + var br metadataReader br.s = s br.offset = offset err := br.parseMetadata() @@ -39,9 +39,9 @@ func (s *Reader) NewMetadataReader(offset int64) (*MetadataReader, error) { } //NewMetadataReaderFromInodeRef creates a new MetadataReader with the offsets set by the given inode reference. -func (s *Reader) NewMetadataReaderFromInodeRef(ref uint64) (*MetadataReader, error) { +func (s *Reader) newMetadataReaderFromInodeRef(ref uint64) (*metadataReader, error) { offset, metaOffset := processInodeRef(ref) - br, err := s.NewMetadataReader(int64(s.super.InodeTableStart + offset)) + br, err := s.newMetadataReader(int64(s.super.InodeTableStart + offset)) if err != nil { return nil, err } @@ -52,7 +52,7 @@ func (s *Reader) NewMetadataReaderFromInodeRef(ref uint64) (*MetadataReader, err return br, nil } -func (br *MetadataReader) parseMetadata() error { +func (br *metadataReader) parseMetadata() error { var raw uint16 err := binary.Read(io.NewSectionReader(br.s.r, br.offset, 2), binary.LittleEndian, &raw) if err != nil { @@ -69,7 +69,7 @@ func (br *MetadataReader) parseMetadata() error { return nil } -func (br *MetadataReader) readNextDataBlock() error { +func (br *metadataReader) readNextDataBlock() error { meta := br.headers[len(br.headers)-1] r := io.NewSectionReader(br.s.r, br.offset, int64(meta.size)) if meta.compressed { @@ -92,7 +92,7 @@ func (br *MetadataReader) readNextDataBlock() error { } //Read reads bytes into the given byte slice. Returns the amount of data read. -func (br *MetadataReader) Read(p []byte) (int, error) { +func (br *metadataReader) Read(p []byte) (int, error) { if br.readOffset+len(p) < len(br.data) { for i := 0; i < len(p); i++ { p[i] = br.data[br.readOffset+i] @@ -130,7 +130,7 @@ func (br *MetadataReader) Read(p []byte) (int, error) { //Seek will seek to the specified location (if possible). Seeking is relative to the uncompressed data. //When io.SeekCurrent or io.SeekStart is set, if seeking would put the offset beyond the current cached data, it will try to read the next data blocks to accomodate. On a failure it will seek to the end of the data. //When io.SeekEnd is set, it wil seek reletive to the currently cached data. -func (br *MetadataReader) Seek(offset int64, whence int) (int64, error) { +func (br *metadataReader) Seek(offset int64, whence int) (int64, error) { switch whence { case io.SeekCurrent: br.readOffset += int(offset) diff --git a/reader.go b/reader.go index 8687ff6..2d09971 100644 --- a/reader.go +++ b/reader.go @@ -3,7 +3,6 @@ package squashfs import ( "encoding/binary" "errors" - "fmt" "io" "math" @@ -30,9 +29,9 @@ var ( //TODO: Give a way to actually read files :P type Reader struct { r io.ReaderAt - super Superblock - flags SuperblockFlags - decompressor Decompressor + super superblock + flags superblockFlags + decompressor decompressor fragOffsets []uint64 } @@ -50,7 +49,7 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) { rdr.flags = rdr.super.GetFlags() switch rdr.super.CompressionType { case gzipCompression: - rdr.decompressor = &ZlibDecompressor{} + rdr.decompressor = &zlibDecompressor{} default: return nil, ErrIncompatibleCompression } @@ -65,7 +64,6 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) { tmp := make([]byte, 8) _, err = r.ReadAt(tmp, offset) if err != nil { - fmt.Println("Error while reading fragment block offsets") return nil, err } rdr.fragOffsets = append(rdr.fragOffsets, binary.LittleEndian.Uint64(tmp)) @@ -76,9 +74,9 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) { } //GetFilesList returns a list of ALL files in the squashfs, going down every folder. -//Paths that terminate in a folder end with / +//Folders end in / func (r *Reader) GetFilesList() ([]string, error) { - inoderdr, err := r.NewMetadataReaderFromInodeRef(r.super.RootInodeRef) + inoderdr, err := r.newMetadataReaderFromInodeRef(r.super.RootInodeRef) if err != nil { return nil, err } @@ -95,20 +93,14 @@ func (r *Reader) GetFilesList() ([]string, error) { //readDir returns a list of all decendents of a given inode. Inode given MUST be a directory type. func (r *Reader) readDir(i *inode.Inode) (paths []string, err error) { - dir, err := r.ReadDirFromInode(i) + dir, err := r.readDirFromInode(i) if err != nil { return } for _, entry := range dir.Entries { - if entry.Init.Type == inode.BasicFileType { - in, _ := r.GetInodeFromEntry(&entry) - fil := in.Info.(inode.BasicFile) - fmt.Println("name:", entry.Name) - fmt.Println("frag index:", fil.Init.FragmentIndex, "frag offset:", fil.Init.FragmentOffset) - } if entry.Init.Type == inode.BasicDirectoryType { paths = append(paths) - i, err = r.GetInodeFromEntry(&entry) + i, err = r.getInodeFromEntry(&entry) if err != nil { return } @@ -128,12 +120,3 @@ func (r *Reader) readDir(i *inode.Inode) (paths []string, err error) { } return } - -//GetFileStructure returns ALL folders and files contained in the squashfs. Folders end with a "/". -func (r *Reader) GetFileStructure() ([]string, error) { - in, err := r.GetInodeFromPath("") - if err != nil { - return nil, err - } - return r.readDir(in) -} diff --git a/superblock.go b/superblock.go index 32623ba..e21910d 100644 --- a/superblock.go +++ b/superblock.go @@ -10,7 +10,7 @@ const ( ) //Superblock contains important information about a squashfs file. Located at the very front of the archive. -type Superblock struct { +type superblock struct { Magic uint32 InodeCount uint32 CreationTime uint32 @@ -33,7 +33,7 @@ type Superblock struct { } //SuperblockFlags is the parsed version of Superblock.Flags -type SuperblockFlags struct { +type superblockFlags struct { UncompressedInodes bool UncompressedData bool Check bool @@ -49,8 +49,8 @@ type SuperblockFlags struct { } //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, diff --git a/utils.go b/utils.go index b2d0a0d..90d694b 100644 --- a/utils.go +++ b/utils.go @@ -27,7 +27,7 @@ func processInodeRef(inodeRef uint64) (tableOffset uint64, metaOffset uint64) { //ReadDirFromInode returns a fully populated directory.Directory from a given inode.Inode. //If the given inode is not a directory it returns an error. -func (r *Reader) ReadDirFromInode(i *inode.Inode) (*directory.Directory, error) { +func (r *Reader) readDirFromInode(i *inode.Inode) (*directory.Directory, error) { var offset uint32 var metaOffset uint16 var size uint16 @@ -43,7 +43,7 @@ func (r *Reader) ReadDirFromInode(i *inode.Inode) (*directory.Directory, error) default: return nil, errors.New("Not a directory inode") } - br, err := r.NewMetadataReader(int64(r.super.DirTableStart + uint64(offset))) + br, err := r.newMetadataReader(int64(r.super.DirTableStart + uint64(offset))) if err != nil { return nil, err } @@ -59,8 +59,8 @@ func (r *Reader) ReadDirFromInode(i *inode.Inode) (*directory.Directory, error) } //GetInodeFromEntry returns the inode associated with a given directory.Entry -func (r *Reader) GetInodeFromEntry(en *directory.Entry) (*inode.Inode, error) { - br, err := r.NewMetadataReader(int64(r.super.InodeTableStart + uint64(en.Header.InodeOffset))) +func (r *Reader) getInodeFromEntry(en *directory.Entry) (*inode.Inode, error) { + br, err := r.newMetadataReader(int64(r.super.InodeTableStart + uint64(en.Header.InodeOffset))) if err != nil { return nil, err } @@ -80,7 +80,7 @@ func (r *Reader) GetInodeFromEntry(en *directory.Entry) (*inode.Inode, error) { func (r *Reader) GetInodeFromPath(path string) (*inode.Inode, error) { path = strings.TrimSuffix(strings.TrimPrefix(path, "/"), "/") pathDirs := strings.Split(path, "/") - rdr, err := r.NewMetadataReaderFromInodeRef(r.super.RootInodeRef) + rdr, err := r.newMetadataReaderFromInodeRef(r.super.RootInodeRef) if err != nil { return nil, err } @@ -95,20 +95,20 @@ func (r *Reader) GetInodeFromPath(path string) (*inode.Inode, error) { if curInodeDir.Type != inode.BasicDirectoryType && curInodeDir.Type != inode.ExtDirType { return nil, ErrNotFound } - dir, err := r.ReadDirFromInode(curInodeDir) + dir, err := r.readDirFromInode(curInodeDir) if err != nil { return nil, err } for _, entry := range dir.Entries { if entry.Name == pathDirs[depth] { if depth == len(pathDirs)-1 { - in, err := r.GetInodeFromEntry(&entry) + in, err := r.getInodeFromEntry(&entry) if err != nil { return nil, err } return in, nil } - curInodeDir, err = r.GetInodeFromEntry(&entry) + curInodeDir, err = r.getInodeFromEntry(&entry) if err != nil { return nil, err }