From be1be40a1769e74ca67ac01d0d8dc930b0f573aa Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Wed, 18 Nov 2020 22:24:26 -0600 Subject: [PATCH] Further work on directory table reading --- blockreader.go | 26 +++++++++++++++++++++++--- internal/directory/directory.go | 21 +++++++++------------ squash_test.go | 2 +- squashfsreader.go | 22 ++++++++-------------- utils.go | 17 +++++++++++++++++ 5 files changed, 58 insertions(+), 30 deletions(-) diff --git a/blockreader.go b/blockreader.go index 89a957e..52d3cfe 100644 --- a/blockreader.go +++ b/blockreader.go @@ -37,6 +37,28 @@ func (s *Reader) NewBlockReader(offset int64) (*BlockReader, error) { return &br, nil } +func (s *Reader) NewBlockReaderFromInodeRef(ref uint64) (*BlockReader, error) { + offset, metaOffset := processInodeRef(ref) + br, err := s.NewBlockReader(int64(s.super.InodeTableStart + offset)) + if err != nil { + return nil, err + } + _, err = br.Seek(int64(metaOffset), io.SeekStart) + if err != nil { + return nil, err + } + return br, nil +} + +func (s *Reader) NewBlockReaderFromDirIndex(index uint64) (*BlockReader, error) { + br, err := s.NewBlockReader(int64(s.super.DirTableStart)) + if err != nil { + return nil, err + } + readIndex := 0 + for readIndex < +} + func (br *BlockReader) parseMetadata() error { var raw uint16 err := binary.Read(io.NewSectionReader(br.s.r, br.offset, 2), binary.LittleEndian, &raw) @@ -77,18 +99,16 @@ func (br *BlockReader) readNextDataBlock() error { } func (br *BlockReader) Read(p []byte) (int, error) { - fmt.Println("reading", len(p)) + fmt.Println("reading", len(p), "bytes") if br.readOffset+len(p) < len(br.data) { for i := 0; i < len(p); i++ { p[i] = br.data[br.readOffset+i] } br.readOffset += len(p) - fmt.Println("enough data available") return len(p), nil } read := 0 for read < len(p) { - fmt.Println("Reading new block") err := br.parseMetadata() if err != nil { br.readOffset += read diff --git a/internal/directory/directory.go b/internal/directory/directory.go index ac7ff00..21ad6b4 100644 --- a/internal/directory/directory.go +++ b/internal/directory/directory.go @@ -4,6 +4,7 @@ import ( "encoding/binary" "fmt" "io" + "math" ) //Header is the header for a directory in the directory table @@ -28,26 +29,25 @@ type Entry struct { } //NewEntry creates a new directory entry -func NewEntry(rdr io.Reader) (Entry, error) { +func NewEntry(rdr io.Reader) (*Entry, error) { var entry Entry err := binary.Read(rdr, binary.LittleEndian, &entry.Init) - fmt.Println("entry", entry.Init) if err != nil { - return Entry{}, err + return nil, err } - entry.Name = make([]byte, entry.Init.NameSize+1, entry.Init.NameSize+1) + entry.Name = make([]byte, entry.Init.NameSize+1) err = binary.Read(rdr, binary.LittleEndian, &entry.Name) if err != nil { - return Entry{}, err + return nil, err } - return entry, err + return &entry, err } //Directory is an entry in the directory table of a squashfs. //Will only have multiple headers if there are more then 256 entries type Directory struct { Headers []Header - Entries []Entry + Entries []*Entry } //NewDirectory reads the directory from rdr @@ -59,22 +59,20 @@ func NewDirectory(rdr io.Reader) (*Directory, error) { return nil, err } hdr.Count++ - fmt.Println("entries coutn", hdr.Count) headers := hdr.Count / 256 if hdr.Count%256 > 0 { headers++ } + fmt.Println("headers", headers) + fmt.Println("headers ceil", math.Ceil(float64(hdr.Count)/256)) headersRead := 1 dir.Headers = make([]Header, headers) dir.Headers[0] = hdr for i := uint32(0); i < hdr.Count; i++ { - fmt.Println("reading entry", i) if i != 0 && i%256 == 0 { - fmt.Println("reading new header...") var newHdr Header err = binary.Read(rdr, binary.LittleEndian, &newHdr) if err != nil { - fmt.Println("Error processing header ", headersRead) return &dir, err } dir.Headers[headersRead] = newHdr @@ -82,7 +80,6 @@ func NewDirectory(rdr io.Reader) (*Directory, error) { } ent, err := NewEntry(rdr) if err != nil { - fmt.Println("Error processing entry ", len(dir.Entries)) return &dir, err } dir.Entries = append(dir.Entries, ent) diff --git a/squash_test.go b/squash_test.go index f893f86..0a1de88 100644 --- a/squash_test.go +++ b/squash_test.go @@ -35,7 +35,7 @@ func TestMain(t *testing.T) { if err != nil { t.Fatal(err) } - err = rdr.readRootDirTable() + err = rdr.readDirTable() if err != nil { t.Fatal(err) } diff --git a/squashfsreader.go b/squashfsreader.go index 619324f..4ab7bd6 100644 --- a/squashfsreader.go +++ b/squashfsreader.go @@ -19,6 +19,7 @@ type Reader struct { super Superblock flags SuperblockFlags decompressor Decompressor + dirs []*directory.Directory } func NewSquashfsReader(r io.ReaderAt) (*Reader, error) { @@ -46,31 +47,24 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) { return &rdr, nil } -func (r *Reader) readRootDirTable() error { - offset, blockOffset := processInodeRef(r.super.RootInodeRef) - br, err := r.NewBlockReader(int64(r.super.InodeTableStart + offset)) +func (r *Reader) readDirTable() error { + inoderdr, err := r.NewBlockReaderFromInodeRef(r.super.RootInodeRef) if err != nil { return err } - _, err = br.Seek(int64(blockOffset), io.SeekStart) + i, err := inode.ProcessInode(inoderdr, r.super.BlockSize) if err != nil { return err } - i, err := inode.ProcessInode(br, r.super.BlockSize) + inDir := i.Info.(inode.BasicDirectory) + dirrdr, err := r.NewBlockReader(int64(r.super.DirTableStart) + int64(inDir.DirectoryIndex)) if err != nil { return err } - fmt.Println("Done reading inode...") - dirRdr, err := r.NewBlockReader(int64(r.super.DirTableStart + uint64(i.Info.(inode.BasicDirectory).DirectoryIndex))) + dir, err := directory.NewDirectory(dirrdr) if err != nil { return err } - dir, err := directory.NewDirectory(dirRdr) - if err != nil { - return err - } - for _, entry := range dir.Entries { - fmt.Println(string(entry.Name)) - } + fmt.Println("Entries", len(dir.Entries)) return nil } diff --git a/utils.go b/utils.go index fd4c605..e95cc74 100644 --- a/utils.go +++ b/utils.go @@ -1,5 +1,12 @@ package squashfs +import ( + "errors" + + "github.com/CalebQ42/GoSquashfs/internal/directory" + "github.com/CalebQ42/GoSquashfs/internal/inode" +) + //ProcessInodeRef processes an inode reference and returns two values // //The first value is the inode table offset. AKA, it's where the metadata block of the inode STARTS relative to the inode table. @@ -10,3 +17,13 @@ func processInodeRef(inodeRef uint64) (tableOffset uint64, metaOffset uint64) { metaOffset = inodeRef &^ 0xFFFFFFFF0000 return } + +func (r *Reader) ReadDirFromInode(i inode.Inode) (*directory.Directory, error) { + if i.Type == inode.BasicDirectoryType { + + } else if i.Type == inode.ExtDirType { + + } else { + return nil, errors.New("Not a directory inode") + } +}