I can now read the entire directory structure.
This commit is contained in:
@@ -20,6 +20,7 @@ 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.
|
||||||
@@ -27,3 +28,7 @@ Thanks also to [distri's squashfs library](https://github.com/distr1/distri/tree
|
|||||||
* 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)
|
||||||
@@ -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 {
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ type EntryInit struct {
|
|||||||
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user