Re-wrote a bunch to try to figure out why things weren't working.
Turned out I was reading if a block was compressed exactly opposite. Started to work more on looking up dirs.
This commit is contained in:
+36
-19
@@ -6,8 +6,25 @@ import (
|
||||
"io"
|
||||
)
|
||||
|
||||
//Common is the comon header for all inodes
|
||||
type Common struct {
|
||||
const (
|
||||
BasicDirectoryType = iota + 1
|
||||
BasicFileType
|
||||
BasicSymlinkType
|
||||
BasicBlockDeviceType
|
||||
BasicCharDeviceType
|
||||
BasicFifoType
|
||||
BasicSocketType
|
||||
ExtDirType
|
||||
ExtFileType
|
||||
ExtSymlinkType
|
||||
ExtBlockDeviceType
|
||||
ExtCharDeviceType
|
||||
ExtFifoType
|
||||
ExtSocketType
|
||||
)
|
||||
|
||||
//Header is the common header for all inodes
|
||||
type Header struct {
|
||||
InodeType uint16
|
||||
Permissions uint16
|
||||
UID uint16
|
||||
@@ -43,9 +60,9 @@ type ExtendedDirectory struct {
|
||||
}
|
||||
|
||||
//NewExtendedDirectory creates a new ExtendedDirectory
|
||||
func NewExtendedDirectory(rdr *io.Reader) (*ExtendedDirectory, error) {
|
||||
func NewExtendedDirectory(rdr io.Reader) (*ExtendedDirectory, error) {
|
||||
var inode ExtendedDirectory
|
||||
err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
|
||||
err := binary.Read(rdr, binary.LittleEndian, &inode.Init)
|
||||
if err != nil {
|
||||
return &inode, err
|
||||
}
|
||||
@@ -76,14 +93,14 @@ type DirectoryIndex struct {
|
||||
}
|
||||
|
||||
//NewDirectoryIndex return a new DirectoryIndex
|
||||
func NewDirectoryIndex(rdr *io.Reader) (DirectoryIndex, error) {
|
||||
func NewDirectoryIndex(rdr io.Reader) (DirectoryIndex, error) {
|
||||
var index DirectoryIndex
|
||||
err := binary.Read(*rdr, binary.LittleEndian, index.Init)
|
||||
err := binary.Read(rdr, binary.LittleEndian, &index.Init)
|
||||
if err != nil {
|
||||
return index, err
|
||||
}
|
||||
index.Name = make([]byte, index.Init.NameSize, index.Init.NameSize)
|
||||
err = binary.Read(*rdr, binary.LittleEndian, index.Name)
|
||||
err = binary.Read(rdr, binary.LittleEndian, &index.Name)
|
||||
return index, err
|
||||
}
|
||||
|
||||
@@ -102,9 +119,9 @@ type BasicFile struct {
|
||||
}
|
||||
|
||||
//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
|
||||
err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
|
||||
err := binary.Read(rdr, binary.LittleEndian, &inode.Init)
|
||||
if err != nil {
|
||||
return &inode, err
|
||||
}
|
||||
@@ -113,7 +130,7 @@ func NewBasicFile(rdr *io.Reader, blockSize uint32) (*BasicFile, error) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -135,9 +152,9 @@ type ExtendedFile struct {
|
||||
}
|
||||
|
||||
//NewExtendedFile creates a new ExtendedFile
|
||||
func NewExtendedFile(rdr *io.Reader, blockSize uint32) (ExtendedFile, error) {
|
||||
func NewExtendedFile(rdr io.Reader, blockSize uint32) (ExtendedFile, error) {
|
||||
var inode ExtendedFile
|
||||
err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
|
||||
err := binary.Read(rdr, binary.LittleEndian, &inode.Init)
|
||||
if err != nil {
|
||||
return inode, err
|
||||
}
|
||||
@@ -146,7 +163,7 @@ func NewExtendedFile(rdr *io.Reader, blockSize uint32) (ExtendedFile, error) {
|
||||
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
|
||||
}
|
||||
|
||||
@@ -163,14 +180,14 @@ type BasicSymlink struct {
|
||||
}
|
||||
|
||||
//NewBasicSymlink creates a new BasicSymlink
|
||||
func NewBasicSymlink(rdr *io.Reader) (BasicSymlink, error) {
|
||||
func NewBasicSymlink(rdr io.Reader) (BasicSymlink, error) {
|
||||
var inode BasicSymlink
|
||||
err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
|
||||
err := binary.Read(rdr, binary.LittleEndian, &inode.Init)
|
||||
if err != nil {
|
||||
return inode, err
|
||||
}
|
||||
inode.targetPath = make([]byte, inode.Init.TargetPathSize, inode.Init.TargetPathSize)
|
||||
err = binary.Read(*rdr, binary.LittleEndian, inode.targetPath)
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode.targetPath)
|
||||
return inode, err
|
||||
}
|
||||
|
||||
@@ -188,14 +205,14 @@ type ExtendedSymlink struct {
|
||||
}
|
||||
|
||||
//NewExtendedSymlink creates a new ExtendedSymlink
|
||||
func NewExtendedSymlink(rdr *io.Reader) (ExtendedSymlink, error) {
|
||||
func NewExtendedSymlink(rdr io.Reader) (ExtendedSymlink, error) {
|
||||
var inode ExtendedSymlink
|
||||
err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
|
||||
err := binary.Read(rdr, binary.LittleEndian, &inode.Init)
|
||||
if err != nil {
|
||||
return inode, err
|
||||
}
|
||||
inode.TargetPath = make([]uint8, inode.Init.TargetPathSize, inode.Init.TargetPathSize)
|
||||
err = binary.Read(*rdr, binary.LittleEndian, &inode.XattrIndex)
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode.XattrIndex)
|
||||
return inode, err
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package inode
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"io"
|
||||
)
|
||||
|
||||
//Inode holds an inode. Header is the header that's common for all inodes.
|
||||
//
|
||||
//Info holds the actual Inode. Due to each inode type being a different type, it's store as an interface{}
|
||||
type Inode struct {
|
||||
Header Header
|
||||
Type int //Type the inode type defined in the header. Here so it's easy to access
|
||||
Info interface{} //Info is the parsed specific data. It's type is defined by Type.
|
||||
}
|
||||
|
||||
//ProcessInode tries to read an inode from the BlockReader
|
||||
func ProcessInode(br io.Reader, blockSize uint32) (Inode, error) {
|
||||
var head Header
|
||||
err := binary.Read(br, binary.LittleEndian, &head)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
var info interface{}
|
||||
switch head.InodeType {
|
||||
case BasicDirectoryType:
|
||||
var inode BasicDirectory
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case BasicFileType:
|
||||
inode, err := NewBasicFile(br, blockSize)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case BasicSymlinkType:
|
||||
inode, err := NewBasicSymlink(br)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case BasicBlockDeviceType:
|
||||
var inode BasicDevice
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case BasicCharDeviceType:
|
||||
var inode BasicDevice
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case BasicFifoType:
|
||||
var inode BasicIPC
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case BasicSocketType:
|
||||
var inode BasicIPC
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case ExtDirType:
|
||||
inode, err := NewExtendedDirectory(br)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case ExtFileType:
|
||||
inode, err := NewExtendedFile(br, blockSize)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case ExtSymlinkType:
|
||||
inode, err := NewExtendedSymlink(br)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case ExtBlockDeviceType:
|
||||
var inode ExtendedDevice
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case ExtCharDeviceType:
|
||||
var inode ExtendedDevice
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case ExtFifoType:
|
||||
var inode ExtendedIPC
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
case ExtSocketType:
|
||||
var inode ExtendedIPC
|
||||
err = binary.Read(br, binary.LittleEndian, &inode)
|
||||
if err != nil {
|
||||
return Inode{}, err
|
||||
}
|
||||
info = inode
|
||||
}
|
||||
return Inode{
|
||||
Type: int(head.InodeType),
|
||||
Header: head,
|
||||
Info: info,
|
||||
}, nil
|
||||
}
|
||||
@@ -1,91 +0,0 @@
|
||||
package inode
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"errors"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
//The inode type from inode.Common.InodeType
|
||||
|
||||
BasicDirectoryType = iota
|
||||
BasicFileType
|
||||
BasicSymlinkType
|
||||
BasicBlockDeviceType
|
||||
BasicCharDeviceType
|
||||
BasicFifoType
|
||||
BasicSocketType
|
||||
ExtendedDirectoryType
|
||||
ExtendedFileType
|
||||
ExtendedSymlinkType
|
||||
ExtendedBlockDeviceType
|
||||
ExtendedCharDeviceType
|
||||
ExtendedFifoType
|
||||
ExtendedSocketType
|
||||
)
|
||||
|
||||
//ProcessInode processes the next inode in the given reader
|
||||
func ProcessInode(rdr io.Reader, blockSize uint32) (*Common, interface{}, error) {
|
||||
var inodeHeader Common
|
||||
err := binary.Read(rdr, binary.LittleEndian, &inodeHeader)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
switch inodeHeader.InodeType {
|
||||
case BasicDirectoryType:
|
||||
var inode BasicDirectory
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, &inode, err
|
||||
case BasicFileType:
|
||||
inode, err := NewBasicFile(&rdr, blockSize)
|
||||
return &inodeHeader, inode, err
|
||||
case BasicSymlinkType:
|
||||
inode, err := NewBasicSymlink(&rdr)
|
||||
return &inodeHeader, inode, err
|
||||
case BasicBlockDeviceType:
|
||||
var inode BasicDevice
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, inode, err
|
||||
case BasicCharDeviceType:
|
||||
var inode BasicDevice
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, inode, err
|
||||
case BasicFifoType:
|
||||
var inode BasicIPC
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, inode, err
|
||||
case BasicSocketType:
|
||||
var inode BasicIPC
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, inode, err
|
||||
case ExtendedDirectoryType:
|
||||
inode, err := NewExtendedDirectory(&rdr)
|
||||
return &inodeHeader, inode, err
|
||||
case ExtendedFileType:
|
||||
inode, err := NewExtendedFile(&rdr, blockSize)
|
||||
return &inodeHeader, inode, err
|
||||
case ExtendedSymlinkType:
|
||||
inode, err := NewExtendedSymlink(&rdr)
|
||||
return &inodeHeader, inode, err
|
||||
case ExtendedBlockDeviceType:
|
||||
var inode ExtendedDevice
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, inode, err
|
||||
case ExtendedCharDeviceType:
|
||||
var inode ExtendedDevice
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, inode, err
|
||||
case ExtendedFifoType:
|
||||
var inode ExtendedIPC
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, inode, err
|
||||
case ExtendedSocketType:
|
||||
var inode ExtendedIPC
|
||||
err = binary.Read(rdr, binary.LittleEndian, &inode)
|
||||
return &inodeHeader, inode, err
|
||||
default:
|
||||
return nil, nil, errors.New("Inode type is unrecognized: " + strconv.FormatInt(int64(inodeHeader.InodeType), 2))
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
package 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.
|
||||
//The second value is the offset of the inode, INSIDE of the metadata.
|
||||
func ProcessInodeRef(inodeRef uint64) (tableOffset uint64, metaOffset uint64) {
|
||||
tableOffset = inodeRef >> 16
|
||||
metaOffset = inodeRef &^ 0xFFFFFFFF0000
|
||||
return
|
||||
}
|
||||
Reference in New Issue
Block a user