I CAN READ A DIRECTORY NOW

I've only tested it with the root dir, but should work for all directories.
This commit is contained in:
Caleb Gardner
2020-11-19 10:50:02 -06:00
parent be1be40a17
commit 87ccd0f346
5 changed files with 74 additions and 60 deletions
-9
View File
@@ -50,15 +50,6 @@ func (s *Reader) NewBlockReaderFromInodeRef(ref uint64) (*BlockReader, error) {
return br, nil 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 { func (br *BlockReader) parseMetadata() error {
var raw uint16 var raw uint16
err := binary.Read(io.NewSectionReader(br.s.r, br.offset, 2), binary.LittleEndian, &raw) err := binary.Read(io.NewSectionReader(br.s.r, br.offset, 2), binary.LittleEndian, &raw)
+43 -39
View File
@@ -1,10 +1,9 @@
package directory package directory
import ( import (
"bytes"
"encoding/binary" "encoding/binary"
"fmt"
"io" "io"
"math"
) )
//Header is the header for a directory in the directory table //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. //Entry is an entry in a directory.
type Entry struct { type Entry struct {
Init EntryInit Init EntryInit
Name []byte Name string
} }
//NewEntry creates a new directory entry //NewEntry creates a new directory entry
func NewEntry(rdr io.Reader) (*Entry, error) { func NewEntry(rdr io.Reader) (Entry, error) {
var entry Entry var entry Entry
err := binary.Read(rdr, binary.LittleEndian, &entry.Init) err := binary.Read(rdr, binary.LittleEndian, &entry.Init)
if err != nil { if err != nil {
return nil, err return Entry{}, err
} }
entry.Name = make([]byte, entry.Init.NameSize+1) tmp := make([]byte, entry.Init.NameSize+1)
err = binary.Read(rdr, binary.LittleEndian, &entry.Name) err = binary.Read(rdr, binary.LittleEndian, &tmp)
if err != nil { 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. //Directory is an entry in the directory table of a squashfs.
//Will only have multiple headers if there are more then 256 entries //Will only have multiple headers if there are more then 256 entries
type Directory struct { type Directory struct {
Headers []Header Headers []Header
Entries []*Entry Entries []Entry
} }
//NewDirectory reads the directory from rdr //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 dir Directory
var hdr Header var err error
err := binary.Read(rdr, binary.LittleEndian, &hdr) tmp := make([]byte, size)
if err != nil { base.Read(tmp)
return nil, err rdr := bytes.NewBuffer(tmp)
} for {
hdr.Count++ var hdr Header
headers := hdr.Count / 256 err = binary.Read(rdr, binary.LittleEndian, &hdr)
if hdr.Count%256 > 0 { if err == io.ErrUnexpectedEOF {
headers++ break
} } else if err != nil {
fmt.Println("headers", headers) return nil, err
fmt.Println("headers ceil", math.Ceil(float64(hdr.Count)/256)) }
headersRead := 1 hdr.Count++
dir.Headers = make([]Header, headers) headers := hdr.Count / 256
dir.Headers[0] = hdr if hdr.Count%256 > 0 {
for i := uint32(0); i < hdr.Count; i++ { headers++
if i != 0 && i%256 == 0 { }
var newHdr Header dir.Headers = append(dir.Headers, hdr)
err = binary.Read(rdr, binary.LittleEndian, &newHdr) for i := uint32(0); i < hdr.Count; i++ {
if err != nil { if i != 0 && i%256 == 0 {
return &dir, err 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 var ent Entry
headersRead++ 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 return &dir, nil
} }
+1 -1
View File
@@ -39,7 +39,7 @@ func TestMain(t *testing.T) {
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
t.Fatal(err) t.Fatal("No problems here!")
} }
func TestCreateSquashFromAppImage(t *testing.T) { func TestCreateSquashFromAppImage(t *testing.T) {
+3 -6
View File
@@ -56,15 +56,12 @@ func (r *Reader) readDirTable() error {
if err != nil { if err != nil {
return err return err
} }
inDir := i.Info.(inode.BasicDirectory) dir, err := r.ReadDirFromInode(i)
dirrdr, err := r.NewBlockReader(int64(r.super.DirTableStart) + int64(inDir.DirectoryIndex))
if err != nil { if err != nil {
return err return err
} }
dir, err := directory.NewDirectory(dirrdr) for _, entry := range dir.Entries {
if err != nil { fmt.Println(entry.Name)
return err
} }
fmt.Println("Entries", len(dir.Entries))
return nil return nil
} }
+27 -5
View File
@@ -2,6 +2,7 @@ package squashfs
import ( import (
"errors" "errors"
"io"
"github.com/CalebQ42/GoSquashfs/internal/directory" "github.com/CalebQ42/GoSquashfs/internal/directory"
"github.com/CalebQ42/GoSquashfs/internal/inode" "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) { func (r *Reader) ReadDirFromInode(i inode.Inode) (*directory.Directory, error) {
if i.Type == inode.BasicDirectoryType { var offset uint32
var metaOffset uint16
} else if i.Type == inode.ExtDirType { var size uint16
switch i.Type {
} else { 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") 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
} }