I can now read the entire directory structure.

This commit is contained in:
Caleb Gardner
2020-11-19 13:27:13 -06:00
parent d43ed54874
commit 33af16071d
6 changed files with 67 additions and 16 deletions
+6 -1
View File
@@ -20,10 +20,15 @@ Thanks also to [distri's squashfs library](https://github.com/distr1/distri/tree
* Give a list of files * Give a list of files
* In string & io.FileStat (?) form * In string & io.FileStat (?) form
* Figure out fragments
* Extracting files * Extracting files
* from inodes. * from inodes.
* from path. * from path.
* from file info. * from file info.
* Reading the UID, GUID, Xatt, Compression Options, Export, and Fragment tables. * Reading the UID, GUID, Xatt, Compression Options, Export, and Fragment tables.
* Implement other compression types (Should be relatively easy) * Implement other compression types (Should be relatively easy)
* Squashing * Squashing
# Where I'm at.
* I CAN READ THE ENTIRE DIRECTORY!!!!! (This is a big ol' step)
-3
View File
@@ -4,7 +4,6 @@ import (
"bytes" "bytes"
"encoding/binary" "encoding/binary"
"errors" "errors"
"fmt"
"io" "io"
) )
@@ -90,7 +89,6 @@ func (br *BlockReader) readNextDataBlock() error {
} }
func (br *BlockReader) Read(p []byte) (int, error) { func (br *BlockReader) Read(p []byte) (int, error) {
fmt.Println("reading", len(p), "bytes")
if br.readOffset+len(p) < len(br.data) { if br.readOffset+len(p) < len(br.data) {
for i := 0; i < len(p); i++ { for i := 0; i < len(p); i++ {
p[i] = br.data[br.readOffset+i] p[i] = br.data[br.readOffset+i]
@@ -111,7 +109,6 @@ func (br *BlockReader) Read(p []byte) (int, error) {
return read, err return read, err
} }
for ; read < len(p); read++ { for ; read < len(p); read++ {
// fmt.Println("Reading...")
if br.readOffset+read < len(br.data) { if br.readOffset+read < len(br.data) {
p[read] = br.data[br.readOffset+read] p[read] = br.data[br.readOffset+read]
} else { } else {
+4 -2
View File
@@ -23,8 +23,9 @@ 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 string Name string
Header *Header
} }
//NewEntry creates a new directory entry //NewEntry creates a new directory entry
@@ -85,6 +86,7 @@ func NewDirectory(base io.Reader, size uint16) (*Directory, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
ent.Header = &dir.Headers[len(dir.Headers)-1]
dir.Entries = append(dir.Entries, ent) dir.Entries = append(dir.Entries, ent)
} }
} }
+9 -7
View File
@@ -60,11 +60,11 @@ type ExtendedDirectory struct {
} }
//NewExtendedDirectory creates a new ExtendedDirectory //NewExtendedDirectory creates a new ExtendedDirectory
func NewExtendedDirectory(rdr io.Reader) (*ExtendedDirectory, error) { func NewExtendedDirectory(rdr io.Reader) (ExtendedDirectory, error) {
var inode ExtendedDirectory var inode ExtendedDirectory
err := binary.Read(rdr, binary.LittleEndian, &inode.Init) err := binary.Read(rdr, binary.LittleEndian, &inode.Init)
if err != nil { if err != nil {
return &inode, err return inode, err
} }
if inode.Init.IndexCount > 0 { if inode.Init.IndexCount > 0 {
inode.Indexes = make([]DirectoryIndex, inode.Init.IndexCount) inode.Indexes = make([]DirectoryIndex, inode.Init.IndexCount)
@@ -72,11 +72,11 @@ func NewExtendedDirectory(rdr io.Reader) (*ExtendedDirectory, error) {
inode.Indexes[i], err = NewDirectoryIndex(rdr) inode.Indexes[i], err = NewDirectoryIndex(rdr)
if err != nil { if err != nil {
fmt.Println("Error while reading Directory Index ", i) fmt.Println("Error while reading Directory Index ", i)
return &inode, err return inode, err
} }
} }
} }
return &inode, err return inode, err
} }
//DirectoryIndexInit holds the values that can be easily decoded //DirectoryIndexInit holds the values that can be easily decoded
@@ -116,22 +116,24 @@ type BasicFileInit struct {
type BasicFile struct { type BasicFile struct {
Init BasicFileInit Init BasicFileInit
BlockSizes []uint32 BlockSizes []uint32
Fragmented bool
} }
//NewBasicFile creates a new BasicFile //NewBasicFile creates a new BasicFile
func NewBasicFile(rdr io.Reader, blockSize uint32) (*BasicFile, error) { func NewBasicFile(rdr io.Reader, blockSize uint32) (BasicFile, error) {
var inode BasicFile var inode BasicFile
err := binary.Read(rdr, binary.LittleEndian, &inode.Init) err := binary.Read(rdr, binary.LittleEndian, &inode.Init)
if err != nil { if err != nil {
return &inode, err return inode, err
} }
inode.Fragmented = inode.Init.FragmentIndex != 0xFFFFFFFF
blocks := inode.Init.Size / blockSize blocks := inode.Init.Size / blockSize
if inode.Init.Size%blockSize > 0 { if inode.Init.Size%blockSize > 0 {
blocks++ blocks++
} }
inode.BlockSizes = make([]uint32, blocks, blocks) inode.BlockSizes = make([]uint32, blocks, blocks)
err = binary.Read(rdr, binary.LittleEndian, &inode.BlockSizes) err = binary.Read(rdr, binary.LittleEndian, &inode.BlockSizes)
return &inode, err return inode, err
} }
//ExtendedFileInit is the information that can be directly decoded //ExtendedFileInit is the information that can be directly decoded
+32 -3
View File
@@ -47,6 +47,35 @@ func NewSquashfsReader(r io.ReaderAt) (*Reader, error) {
return &rdr, nil return &rdr, nil
} }
func (r *Reader) readDir(i *inode.Inode) (paths []string, err error) {
dir, err := r.ReadDirFromInode(*i)
if err != nil {
return
}
for _, entry := range dir.Entries {
if entry.Init.Type == inode.BasicDirectoryType {
paths = append(paths)
i, err = r.GetInodeFromEntry(&entry)
if err != nil {
return
}
var subPaths []string
subPaths, err = r.readDir(i)
if err != nil {
return
}
for pathI := range subPaths {
subPaths[pathI] = entry.Name + "/" + subPaths[pathI]
}
paths = append(paths, entry.Name+"/")
paths = append(paths, subPaths...)
} else {
paths = append(paths, entry.Name)
}
}
return
}
func (r *Reader) readDirTable() error { func (r *Reader) readDirTable() error {
inoderdr, err := r.NewBlockReaderFromInodeRef(r.super.RootInodeRef) inoderdr, err := r.NewBlockReaderFromInodeRef(r.super.RootInodeRef)
if err != nil { if err != nil {
@@ -56,12 +85,12 @@ func (r *Reader) readDirTable() error {
if err != nil { if err != nil {
return err return err
} }
dir, err := r.ReadDirFromInode(i) paths, err := r.readDir(&i)
if err != nil { if err != nil {
return err return err
} }
for _, entry := range dir.Entries { for _, path := range paths {
fmt.Println(entry.Name) fmt.Println(path)
} }
return nil return nil
} }
+16
View File
@@ -49,3 +49,19 @@ func (r *Reader) ReadDirFromInode(i inode.Inode) (*directory.Directory, error) {
} }
return dir, nil return dir, nil
} }
func (r *Reader) GetInodeFromEntry(en *directory.Entry) (*inode.Inode, error) {
br, err := r.NewBlockReader(int64(r.super.InodeTableStart + uint64(en.Header.InodeOffset)))
if err != nil {
return nil, err
}
_, err = br.Seek(int64(en.Init.Offset), io.SeekStart)
if err != nil {
return nil, err
}
i, err := inode.ProcessInode(br, r.super.BlockSize)
if err != nil {
return nil, err
}
return &i, nil
}