Further work on directory table reading
This commit is contained in:
+23
-3
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
+1
-1
@@ -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)
|
||||
}
|
||||
|
||||
+8
-14
@@ -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
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user