Files
Caleb Gardner b2c8084f41 Minor tweaks
2025-06-06 15:46:25 -05:00

145 lines
2.5 KiB
Go

package inode
import (
"encoding/binary"
"errors"
"io"
"io/fs"
"strconv"
)
const (
Dir = uint16(iota + 1)
Fil
Sym
Block
Char
Fifo
Sock
EDir
EFil
ESym
EBlock
EChar
EFifo
ESock
)
type Header struct {
Type uint16
Perm uint16
UidInd uint16
GidInd uint16
ModTime uint32
Num uint32
}
type Inode struct {
Header
Data any
}
func Read(r io.Reader, blockSize uint32) (i Inode, err error) {
dat := make([]byte, 16)
_, err = r.Read(dat)
if err != nil {
return
}
i.Type = binary.LittleEndian.Uint16(dat[0:2])
i.Perm = binary.LittleEndian.Uint16(dat[2:4])
i.UidInd = binary.LittleEndian.Uint16(dat[4:6])
i.GidInd = binary.LittleEndian.Uint16(dat[6:8])
i.ModTime = binary.LittleEndian.Uint32(dat[8:12])
i.Num = binary.LittleEndian.Uint32(dat[12:16])
switch i.Type {
case Dir:
i.Data, err = ReadDir(r)
case Fil:
i.Data, err = ReadFile(r, blockSize)
case Sym:
i.Data, err = ReadSym(r)
case Block:
fallthrough
case Char:
i.Data, err = ReadDevice(r)
case Fifo:
fallthrough
case Sock:
i.Data, err = ReadIPC(r)
case EDir:
i.Data, err = ReadEDir(r)
case EFil:
i.Data, err = ReadEFile(r, blockSize)
case ESym:
i.Data, err = ReadESym(r)
case EBlock:
fallthrough
case EChar:
i.Data, err = ReadEDevice(r)
case EFifo:
fallthrough
case ESock:
i.Data, err = ReadEIPC(r)
default:
return i, errors.New("invalid inode type " + strconv.Itoa(int(i.Type)))
}
return
}
func (i Inode) Mode() (out fs.FileMode) {
out = fs.FileMode(i.Perm)
switch i.Type {
case Dir, EDir:
out |= fs.ModeDir
case Sym, ESym:
out |= fs.ModeSymlink
case Char, EChar, Block, EBlock:
out |= fs.ModeDevice
case Fifo, EFifo:
out |= fs.ModeNamedPipe
case Sock, ESock:
out |= fs.ModeSocket
}
return
}
func (i Inode) LinkCount() uint32 {
switch i.Data.(type) {
case EFile:
return i.Data.(EFile).LinkCount
case Directory:
return i.Data.(Directory).LinkCount
case EDirectory:
return i.Data.(EDirectory).LinkCount
case Device:
return i.Data.(Device).LinkCount
case EDevice:
return i.Data.(EDevice).LinkCount
case IPC:
return i.Data.(IPC).LinkCount
case EIPC:
return i.Data.(EIPC).LinkCount
case Symlink:
return i.Data.(Symlink).LinkCount
case ESymlink:
return i.Data.(ESymlink).LinkCount
default:
return 0
}
}
func (i Inode) Size() uint64 {
switch i.Data.(type) {
case File:
return uint64(i.Data.(File).Size)
case EFile:
return i.Data.(EFile).Size
// case Directory:
// return uint64(i.Data.(Directory).Size)
// case EDirectory:
// return uint64(i.Data.(EDirectory).Size)
default:
return 0
}
}