Directorty table info parsing.

Futher work on reading data.
This commit is contained in:
Caleb Gardner
2020-11-13 04:47:54 -06:00
parent f135457443
commit dbf7e9465a
9 changed files with 288 additions and 114 deletions
+58 -18
View File
@@ -2,11 +2,12 @@ package inode
import (
"encoding/binary"
"fmt"
"io"
)
//InodeCommon is the comon header for all inodes
type InodeCommon struct {
//Common is the comon header for all inodes
type Common struct {
InodeType uint16
Permissions uint16
UID uint16
@@ -37,25 +38,61 @@ type ExtendedDirectoryInit struct {
//ExtendedDirectory is a directory with extra info
type ExtendedDirectory struct {
Init ExtendedDirectoryInit
//TODO: indexes []DirectoryIndex
Init ExtendedDirectoryInit
Indexes []DirectoryIndex
}
//NewExtendedDirectory creates a new ExtendedDirectory
func NewExtendedDirectory(rdr *io.Reader) (*ExtendedDirectory, error) {
var inode ExtendedDirectory
err := binary.Read(*rdr, binary.LittleEndian, inode.Init)
//TODO: Read directory indexes
if err != nil {
return &inode, err
}
if inode.Init.IndexCount > 0 {
inode.Indexes = make([]DirectoryIndex, inode.Init.IndexCount)
for i := uint16(0); i < inode.Init.IndexCount; i++ {
inode.Indexes[i], err = NewDirectoryIndex(rdr)
if err != nil {
fmt.Println("Error while reading Directory Index ", i)
return &inode, err
}
}
}
return &inode, err
}
//DirectoryIndexInit holds the values that can be easily decoded
type DirectoryIndexInit struct {
Offset uint32
DirTableOffset uint32
NameSize uint32
}
//DirectoryIndex is a quick lookup provided by an ExtendedDirectory
type DirectoryIndex struct {
Init DirectoryIndexInit
Name []byte
}
//NewDirectoryIndex return a new DirectoryIndex
func NewDirectoryIndex(rdr *io.Reader) (DirectoryIndex, error) {
var index DirectoryIndex
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)
return index, err
}
//BasicFileInit is the information that can be directoy decoded
type BasicFileInit struct {
BlockStart uint32
FragmentIndex uint32
FragmentOffset uint32
Size uint32
//TODO: possibly fix BlockSizes
}
//BasicFile is self explainatory
@@ -89,7 +126,6 @@ type ExtendedFileInit struct {
FragmentIndex uint32
FragmentOffset uint32
XattrIndex uint32
//TODO: possibly fix BlockSizes
}
//ExtendedFile is a file with more information
@@ -99,11 +135,11 @@ 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)
if err != nil {
return &inode, err
return inode, err
}
blocks := inode.Init.Size / blockSize
if inode.Init.Size%blockSize > 0 {
@@ -111,7 +147,7 @@ func NewExtendedFile(rdr *io.Reader, blockSize uint32) (*ExtendedFile, error) {
}
inode.BlockSizes = make([]uint32, blocks, blocks)
err = binary.Read(*rdr, binary.LittleEndian, inode.BlockSizes)
return &inode, err
return inode, err
}
//BasicSymlinkInit is all the values that can be directly decoded
@@ -123,19 +159,19 @@ type BasicSymlinkInit struct {
//BasicSymlink is a symlink
type BasicSymlink struct {
Init BasicSymlinkInit
targetPath []uint8 //len is TargetPathSize
targetPath []byte //len is TargetPathSize
}
//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)
if err != nil {
return nil, err
return inode, err
}
inode.targetPath = make([]uint8, inode.Init.TargetPathSize, inode.Init.TargetPathSize)
inode.targetPath = make([]byte, inode.Init.TargetPathSize, inode.Init.TargetPathSize)
err = binary.Read(*rdr, binary.LittleEndian, inode.targetPath)
return &inode, err
return inode, err
}
//ExtendedSymlinkInit is all the values that can be directly decoded
@@ -152,31 +188,35 @@ 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)
if err != nil {
return &inode, err
return inode, err
}
inode.TargetPath = make([]uint8, inode.Init.TargetPathSize, inode.Init.TargetPathSize)
err = binary.Read(*rdr, binary.LittleEndian, &inode.XattrIndex)
return &inode, err
return inode, err
}
//BasicDevice is a device
type BasicDevice struct {
HardLinks uint32
Device uint32
}
//ExtendedDevice is a device with more info
type ExtendedDevice struct {
BasicDevice
XattrIndex uint32
}
//BasicIPC is a Fifo or Socket device
type BasicIPC struct {
HardLink uint32
}
//ExtendedIPC is a IPC device with extra info
type ExtendedIPC struct {
BasicIPC
XattrIndex uint32
+65 -62
View File
@@ -8,80 +8,83 @@ import (
)
const (
basicDirectory = iota + 1
basicFile
basicSymlink
basicBlockDevice
basicCharDevice
basicFifo
basicSocket
extendedDirectory
extendedFile
extendedSymlink
extendedBlockDevice
extendedCharDevice
extendedFifo
extendedSocket
//The inode type from inode.Common.InodeType
BasicDirectoryType = iota + 1
BasicFileType
BasicSymlinkType
BasicBlockDeviceType
BasicCharDeviceType
BasicFifoType
BasicSocketType
ExtendedDirectoryType
ExtendedFileType
ExtendedSymlinkType
ExtendedBlockDeviceType
ExtendedCharDeviceType
ExtendedFifoType
ExtendedSocketType
)
func ProcessInode(rdr *io.Reader) (*InodeCommon, interface{}, error) {
var inodeHeader InodeCommon
//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 basicDirectory:
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 basicFile:
var inode BasicFile
err = binary.Read(*rdr, binary.LittleEndian, &inode)
return &inodeHeader, inode, err
case basicSymlink:
case BasicSymlinkType:
inode, err := NewBasicSymlink(rdr)
return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// return &inodeHeader, inode, err
// case basicFile:
// var inode BasicFile
// err = binary.Read(*rdr, binary.LittleEndian, &inode)
// 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
//TODO: implement ALL cases
default:
return nil, nil, errors.New("Inode type is unrecognized: " + strconv.FormatInt(int64(inodeHeader.InodeType), 2))
+10
View File
@@ -0,0 +1,10 @@
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 uint32, metaOffset uint16) {
tableOffset = uint32(inodeRef >> 16)
metaOffset = uint16(inodeRef &^ 0xFFFFFFFF0000)
return
}