257 lines
5.6 KiB
Go
257 lines
5.6 KiB
Go
package inode
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"io"
|
|
)
|
|
|
|
//The different types of inodes as defined by inodetype
|
|
const (
|
|
DirType = iota + 1
|
|
FileType
|
|
SymType
|
|
BlockDevType
|
|
CharDevType
|
|
FifoType
|
|
SocketType
|
|
ExtDirType
|
|
ExtFileType
|
|
ExtSymlinkType
|
|
ExtBlockDeviceType
|
|
ExtCharDeviceType
|
|
ExtFifoType
|
|
ExtSocketType
|
|
)
|
|
|
|
//Header is the common header for all inodes
|
|
type Header struct {
|
|
InodeType uint16
|
|
Permissions uint16
|
|
UID uint16
|
|
GID uint16
|
|
ModifiedTime uint32
|
|
Number uint32
|
|
}
|
|
|
|
//Dir is self explainatory
|
|
type Dir struct {
|
|
DirectoryIndex uint32
|
|
HardLinks uint32
|
|
DirectorySize uint16
|
|
DirectoryOffset uint16
|
|
ParentInodeNumber uint32
|
|
}
|
|
|
|
//ExtDirInit is the information that can be directoy decoded
|
|
type ExtDirInit struct {
|
|
HardLinks uint32
|
|
DirectorySize uint32
|
|
DirectoryIndex uint32
|
|
ParentInodeNumber uint32
|
|
IndexCount uint16 //one less then directory indexes following structure
|
|
DirectoryOffset uint16
|
|
XattrIndex uint32
|
|
}
|
|
|
|
//ExtDir is a directory with extra info
|
|
type ExtDir struct {
|
|
Indexes []DirIndex
|
|
ExtDirInit
|
|
}
|
|
|
|
//NewExtendedDirectory creates a new ExtendedDirectory
|
|
func NewExtendedDirectory(rdr io.Reader) (ExtDir, error) {
|
|
var inode ExtDir
|
|
err := binary.Read(rdr, binary.LittleEndian, &inode.ExtDirInit)
|
|
if err != nil {
|
|
return inode, err
|
|
}
|
|
for i := uint16(0); i < inode.IndexCount; i++ {
|
|
tmp, err := NewDirectoryIndex(rdr)
|
|
if err != nil {
|
|
return inode, err
|
|
}
|
|
inode.Indexes = append(inode.Indexes, tmp)
|
|
}
|
|
return inode, err
|
|
}
|
|
|
|
//DirIndexInit holds the values that can be easily decoded
|
|
type DirIndexInit struct {
|
|
Offset uint32
|
|
DirTableOffset uint32
|
|
NameSize uint32
|
|
}
|
|
|
|
//DirIndex is a quick lookup provided by an ExtendedDirectory
|
|
type DirIndex struct {
|
|
Name string
|
|
DirIndexInit
|
|
}
|
|
|
|
//NewDirectoryIndex return a new DirectoryIndex
|
|
func NewDirectoryIndex(rdr io.Reader) (DirIndex, error) {
|
|
var index DirIndex
|
|
err := binary.Read(rdr, binary.LittleEndian, &index.DirIndexInit)
|
|
if err != nil {
|
|
return index, err
|
|
}
|
|
tmp := make([]byte, index.NameSize+1, index.NameSize+1)
|
|
err = binary.Read(rdr, binary.LittleEndian, &tmp)
|
|
if err != nil {
|
|
return index, err
|
|
}
|
|
index.Name = string(tmp)
|
|
return index, nil
|
|
}
|
|
|
|
//FileInit is the information that can be directly decoded
|
|
type FileInit struct {
|
|
BlockStart uint32
|
|
FragmentIndex uint32
|
|
FragmentOffset uint32
|
|
Size uint32
|
|
}
|
|
|
|
//File is self explainatory
|
|
type File struct {
|
|
BlockSizes []uint32
|
|
Fragmented bool
|
|
FileInit
|
|
}
|
|
|
|
//NewFile creates a new File
|
|
func NewFile(rdr io.Reader, blockSize uint32) (File, error) {
|
|
var inode File
|
|
err := binary.Read(rdr, binary.LittleEndian, &inode.FileInit)
|
|
if err != nil {
|
|
return inode, err
|
|
}
|
|
inode.Fragmented = inode.FragmentIndex != 0xFFFFFFFF
|
|
blocks := inode.Size / blockSize
|
|
if inode.Size%blockSize > 0 {
|
|
blocks++
|
|
}
|
|
inode.BlockSizes = make([]uint32, blocks, blocks)
|
|
err = binary.Read(rdr, binary.LittleEndian, &inode.BlockSizes)
|
|
return inode, err
|
|
}
|
|
|
|
//ExtFileInit is the information that can be directly decoded
|
|
type ExtFileInit struct {
|
|
BlockStart uint32
|
|
Size uint32
|
|
Sparse uint64
|
|
HardLinks uint32
|
|
FragmentIndex uint32
|
|
FragmentOffset uint32
|
|
XattrIndex uint32
|
|
}
|
|
|
|
//ExtFile is a file with more information
|
|
type ExtFile struct {
|
|
BlockSizes []uint32
|
|
Fragmented bool
|
|
ExtFileInit
|
|
}
|
|
|
|
//NewExtendedFile creates a new ExtendedFile
|
|
func NewExtendedFile(rdr io.Reader, blockSize uint32) (ExtFile, error) {
|
|
var inode ExtFile
|
|
err := binary.Read(rdr, binary.LittleEndian, &inode.ExtFileInit)
|
|
if err != nil {
|
|
return inode, err
|
|
}
|
|
inode.Fragmented = inode.FragmentIndex != 0xFFFFFFFF
|
|
blocks := inode.Size / blockSize
|
|
if inode.Size%blockSize > 0 {
|
|
blocks++
|
|
}
|
|
inode.BlockSizes = make([]uint32, blocks, blocks)
|
|
err = binary.Read(rdr, binary.LittleEndian, &inode.BlockSizes)
|
|
return inode, err
|
|
}
|
|
|
|
//SymInit is all the values that can be directly decoded
|
|
type SymInit struct {
|
|
HardLinks uint32
|
|
TargetPathSize uint32
|
|
}
|
|
|
|
//Sym is a symlink
|
|
type Sym struct {
|
|
Path string
|
|
targetPath []byte //len is TargetPathSize
|
|
SymInit
|
|
}
|
|
|
|
//NewSymlink creates a new Symlink
|
|
func NewSymlink(rdr io.Reader) (Sym, error) {
|
|
var inode Sym
|
|
err := binary.Read(rdr, binary.LittleEndian, &inode.SymInit)
|
|
if err != nil {
|
|
return inode, err
|
|
}
|
|
inode.targetPath = make([]byte, inode.TargetPathSize, inode.TargetPathSize)
|
|
err = binary.Read(rdr, binary.LittleEndian, &inode.targetPath)
|
|
if err != nil {
|
|
return inode, err
|
|
}
|
|
inode.Path = string(inode.targetPath)
|
|
return inode, err
|
|
}
|
|
|
|
//ExtSymInit is all the values that can be directly decoded
|
|
type ExtSymInit struct {
|
|
HardLinks uint32
|
|
TargetPathSize uint32
|
|
}
|
|
|
|
//ExtSym is a symlink with extra information
|
|
type ExtSym struct {
|
|
Path string
|
|
targetPath []uint8
|
|
ExtSymInit
|
|
XattrIndex uint32
|
|
}
|
|
|
|
//NewExtendedSymlink creates a new ExtendedSymlink
|
|
func NewExtendedSymlink(rdr io.Reader) (ExtSym, error) {
|
|
var inode ExtSym
|
|
err := binary.Read(rdr, binary.LittleEndian, &inode.ExtSymInit)
|
|
if err != nil {
|
|
return inode, err
|
|
}
|
|
inode.targetPath = make([]uint8, inode.TargetPathSize, inode.TargetPathSize)
|
|
err = binary.Read(rdr, binary.LittleEndian, &inode.targetPath)
|
|
if err != nil {
|
|
return inode, err
|
|
}
|
|
inode.Path = string(inode.targetPath)
|
|
err = binary.Read(rdr, binary.LittleEndian, &inode.XattrIndex)
|
|
return inode, err
|
|
}
|
|
|
|
//Device is a device
|
|
type Device struct {
|
|
HardLinks uint32
|
|
Device uint32
|
|
}
|
|
|
|
//ExtDevice is a device with more info
|
|
type ExtDevice struct {
|
|
Device
|
|
XattrIndex uint32
|
|
}
|
|
|
|
//IPC is a Fifo or Socket device
|
|
type IPC struct {
|
|
HardLink uint32
|
|
}
|
|
|
|
//ExtIPC is a IPC device with extra info
|
|
type ExtIPC struct {
|
|
IPC
|
|
XattrIndex uint32
|
|
}
|