From 87ccd0f346c236f7133d17726cb66824b040f462 Mon Sep 17 00:00:00 2001 From: Caleb Gardner Date: Thu, 19 Nov 2020 10:50:02 -0600 Subject: [PATCH] I CAN READ A DIRECTORY NOW I've only tested it with the root dir, but should work for all directories. --- blockreader.go | 9 ---- internal/directory/directory.go | 82 +++++++++++++++++---------------- squash_test.go | 2 +- squashfsreader.go | 9 ++-- utils.go | 32 +++++++++++-- 5 files changed, 74 insertions(+), 60 deletions(-) diff --git a/blockreader.go b/blockreader.go index 52d3cfe..476402c 100644 --- a/blockreader.go +++ b/blockreader.go @@ -50,15 +50,6 @@ func (s *Reader) NewBlockReaderFromInodeRef(ref uint64) (*BlockReader, error) { 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) diff --git a/internal/directory/directory.go b/internal/directory/directory.go index 21ad6b4..e86146d 100644 --- a/internal/directory/directory.go +++ b/internal/directory/directory.go @@ -1,10 +1,9 @@ package directory import ( + "bytes" "encoding/binary" - "fmt" "io" - "math" ) //Header is the header for a directory in the directory table @@ -25,64 +24,69 @@ type EntryInit struct { //Entry is an entry in a directory. type Entry struct { Init EntryInit - Name []byte + Name string } //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) if err != nil { - return nil, err + return Entry{}, err } - entry.Name = make([]byte, entry.Init.NameSize+1) - err = binary.Read(rdr, binary.LittleEndian, &entry.Name) + tmp := make([]byte, entry.Init.NameSize+1) + err = binary.Read(rdr, binary.LittleEndian, &tmp) if err != nil { - return nil, err + return Entry{}, err } - return &entry, err + entry.Name = string(tmp) + 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 -func NewDirectory(rdr io.Reader) (*Directory, error) { +func NewDirectory(base io.Reader, size uint16) (*Directory, error) { var dir Directory - var hdr Header - err := binary.Read(rdr, binary.LittleEndian, &hdr) - if err != nil { - return nil, err - } - 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++ { - if i != 0 && i%256 == 0 { - var newHdr Header - err = binary.Read(rdr, binary.LittleEndian, &newHdr) - if err != nil { - return &dir, err + var err error + tmp := make([]byte, size) + base.Read(tmp) + rdr := bytes.NewBuffer(tmp) + for { + var hdr Header + err = binary.Read(rdr, binary.LittleEndian, &hdr) + if err == io.ErrUnexpectedEOF { + break + } else if err != nil { + return nil, err + } + hdr.Count++ + headers := hdr.Count / 256 + if hdr.Count%256 > 0 { + headers++ + } + dir.Headers = append(dir.Headers, hdr) + for i := uint32(0); i < hdr.Count; i++ { + if i != 0 && i%256 == 0 { + var newHdr Header + err = binary.Read(rdr, binary.LittleEndian, &newHdr) + if err != nil { + return nil, err + } + dir.Headers = append(dir.Headers, newHdr) } - dir.Headers[headersRead] = newHdr - headersRead++ + var ent Entry + ent, err = NewEntry(rdr) + if err != nil { + return nil, err + } + dir.Entries = append(dir.Entries, ent) } - ent, err := NewEntry(rdr) - if err != nil { - return &dir, err - } - dir.Entries = append(dir.Entries, ent) } return &dir, nil } diff --git a/squash_test.go b/squash_test.go index 0a1de88..4fafc99 100644 --- a/squash_test.go +++ b/squash_test.go @@ -39,7 +39,7 @@ func TestMain(t *testing.T) { if err != nil { t.Fatal(err) } - t.Fatal(err) + t.Fatal("No problems here!") } func TestCreateSquashFromAppImage(t *testing.T) { diff --git a/squashfsreader.go b/squashfsreader.go index 4ab7bd6..a41c457 100644 --- a/squashfsreader.go +++ b/squashfsreader.go @@ -56,15 +56,12 @@ func (r *Reader) readDirTable() error { if err != nil { return err } - inDir := i.Info.(inode.BasicDirectory) - dirrdr, err := r.NewBlockReader(int64(r.super.DirTableStart) + int64(inDir.DirectoryIndex)) + dir, err := r.ReadDirFromInode(i) if err != nil { return err } - dir, err := directory.NewDirectory(dirrdr) - if err != nil { - return err + for _, entry := range dir.Entries { + fmt.Println(entry.Name) } - fmt.Println("Entries", len(dir.Entries)) return nil } diff --git a/utils.go b/utils.go index e95cc74..7589152 100644 --- a/utils.go +++ b/utils.go @@ -2,6 +2,7 @@ package squashfs import ( "errors" + "io" "github.com/CalebQ42/GoSquashfs/internal/directory" "github.com/CalebQ42/GoSquashfs/internal/inode" @@ -19,11 +20,32 @@ func processInodeRef(inodeRef uint64) (tableOffset uint64, metaOffset uint64) { } func (r *Reader) ReadDirFromInode(i inode.Inode) (*directory.Directory, error) { - if i.Type == inode.BasicDirectoryType { - - } else if i.Type == inode.ExtDirType { - - } else { + var offset uint32 + var metaOffset uint16 + var size uint16 + switch i.Type { + case inode.BasicDirectoryType: + offset = i.Info.(inode.BasicDirectory).DirectoryIndex + metaOffset = i.Info.(inode.BasicDirectory).DirectoryOffset + size = i.Info.(inode.BasicDirectory).DirectorySize + case inode.ExtDirType: + offset = i.Info.(inode.ExtendedDirectory).Init.DirectoryIndex + metaOffset = i.Info.(inode.ExtendedDirectory).Init.DirectoryOffset + size = uint16(i.Info.(inode.ExtendedDirectory).Init.DirectorySize) + default: return nil, errors.New("Not a directory inode") } + br, err := r.NewBlockReader(int64(r.super.DirTableStart + uint64(offset))) + if err != nil { + return nil, err + } + _, err = br.Seek(int64(metaOffset), io.SeekStart) + if err != nil { + return nil, err + } + dir, err := directory.NewDirectory(br, size) + if err != nil { + return dir, err + } + return dir, nil }