squashfs

package module
v1.0.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 8, 2022 License: MIT Imports: 15 Imported by: 0

README

GoDoc

squashfs

This is a read-only implementation of squashfs initially meant to be use with go-fuse.

Since then, golang added io/fs and fuse support was moved to a fuse tag, which means this module can be either used with go-fuse, or as a simple io/fs-compliant squashfs file reader.

Tags

The following tags can be specified on build to enable/disable features:

  • fuse adds methods to the Inode object to interact with fuse
  • xz adds a dependency on xz to support xz compressed files
  • zstd adds a dependency on zstd to support zstd compressed files

Example use

sqfs, err := squashfs.Open("file.squashfs")
if err != nil {
	return err
}
defer sqfs.Close()
// sqfs can be used as a regular fs.FS
data, err := fs.ReadFile(sqfs, "dir/file.txt")
// or:
http.Handle("/", http.FileServer(sqfs))
// etc...

You can find more looking at the test file.

File format

Some documentation is available online on SquashFS.

TODO

Access to directories do not currently use indexes and can be slow for random file accesses in very large directories.

Documentation

Index

Constants

View Source
const SuperblockSize = 96

Variables

View Source
var (
	ErrInvalidFile      = errors.New("invalid file, squashfs signature not found")
	ErrInvalidSuper     = errors.New("invalid squashfs superblock")
	ErrInvalidVersion   = errors.New("invalid file version, expected squashfs 4.0")
	ErrInodeNotExported = errors.New("unknown squashfs inode and no NFS export table")
	ErrNotDirectory     = errors.New("Not a directory")
	ErrTooManySymlinks  = errors.New("Too many levels of symbolic links")
)

Functions

func RegisterDecompressor

func RegisterDecompressor(method Compression, dcomp Decompressor)

RegisterDecompressor can be used to register a decompressor for squashfs. By default GZip is supported. The method shall take a buffer and return a decompressed buffer.

Types

type Compression added in v0.1.4

type Compression uint16
const (
	GZip Compression = iota + 1
	LZMA
	LZO
	XZ
	LZ4
	ZSTD
)

func (Compression) String added in v0.1.4

func (s Compression) String() string

type Decompressor

type Decompressor func(buf []byte) ([]byte, error)

func MakeDecompressor

func MakeDecompressor(dec func(r io.Reader) io.ReadCloser) Decompressor

MakeDecompressor allows using a decompressor made for archive/zip with SquashFs. It has some overhead as instead of simply dealing with buffer this uses the reader/writer API, but should allow to easily handle some formats.

Example use: * squashfs.RegisterDecompressor(squashfs.ZSTD, squashfs.MakeDecompressor(zstd.ZipDecompressor())) * squashfs.RegisterDecompressor(squashfs.LZ4, squashfs.MakeDecompressor(lz4.NewReader)))

func MakeDecompressorErr added in v0.1.4

func MakeDecompressorErr(dec func(r io.Reader) (io.ReadCloser, error)) Decompressor

MakeDecompressorErr is similar to MakeDecompressor but the factory method also returns an error.

Example use: * squashfs.RegisterDecompressor(squashfs.LZMA, squashfs.MakeDecompressorErr(lzma.NewReader)) * squashfs.RegisterDecompressor(squashfs.XZ, squashfs.MakeDecompressorErr(xz.NewReader))

type File

type File struct {
	*io.SectionReader
	// contains filtered or unexported fields
}

File is a convience object allowing using an inode as if it was a regular file

func (*File) Close

func (f *File) Close() error

Close actually does nothing and exists to comply with fs.File

func (*File) Stat

func (f *File) Stat() (fs.FileInfo, error)

Stat returns the details of the open file

func (*File) Sys added in v0.1.5

func (f *File) Sys() any

Sys returns a *Inode object for this file

type FileDir

type FileDir struct {
	// contains filtered or unexported fields
}

FileDir is a convenience object allowing using a dir inode as if it was a regular file

func (*FileDir) Close

func (d *FileDir) Close() error

Close resets the dir reader

func (*FileDir) Read

func (d *FileDir) Read(p []byte) (int, error)

Read on a directory is invalid and will always fail

func (*FileDir) ReadDir

func (d *FileDir) ReadDir(n int) ([]fs.DirEntry, error)

func (*FileDir) Stat

func (d *FileDir) Stat() (fs.FileInfo, error)

Stat returns details on the file

func (*FileDir) Sys added in v0.1.5

func (d *FileDir) Sys() any

Sys returns a *inode object for this file, similar to calling Stat().Sys()

type Flags added in v0.1.4

type Flags uint16
const (
	UNCOMPRESSED_INODES Flags = 1 << iota
	UNCOMPRESSED_DATA
	CHECK
	UNCOMPRESSED_FRAGMENTS
	NO_FRAGMENTS
	ALWAYS_FRAGMENTS
	DUPLICATES
	EXPORTABLE
	UNCOMPRESSED_XATTRS
	NO_XATTRS
	COMPRESSOR_OPTIONS
	UNCOMPRESSED_IDS
)

func (Flags) Has added in v0.1.4

func (f Flags) Has(what Flags) bool

func (Flags) String added in v0.1.4

func (f Flags) String() string

type Inode

type Inode struct {
	Type    Type
	Perm    uint16
	UidIdx  uint16
	GidIdx  uint16
	ModTime int32
	Ino     uint32 // inode number

	StartBlock uint64
	NLink      uint32
	Size       uint64 // Careful, actual on disk size varies depending on type
	Offset     uint32 // uint16 for directories
	ParentIno  uint32 // for directories
	SymTarget  []byte // The target path this symlink points to
	IdxCount   uint16 // index count for advanced directories
	XattrIdx   uint32 // xattr table index (if relevant)
	Sparse     uint64

	// fragment
	FragBlock uint32
	FragOfft  uint32

	// file blocks (some have value 0x1001000)
	Blocks     []uint32
	BlocksOfft []uint64
	// contains filtered or unexported fields
}

func (*Inode) AddRef

func (i *Inode) AddRef(count uint64) uint64

AddRef atomatically increments the inode's refcount and returns the new value. This is mainly useful when using fuse and can be safely ignored.

func (*Inode) DelRef

func (i *Inode) DelRef(count uint64) uint64

DelRef atomatically decrements the inode's refcount and returns the new value. This is mainly useful when using fuse and can be safely ignored.

func (*Inode) GetGid added in v0.1.5

func (i *Inode) GetGid() uint32

GetGid returns inode's group id, or zero if an error happens

func (*Inode) GetUid added in v0.1.5

func (i *Inode) GetUid() uint32

GetUid returns inode's owner uid, or zero if an error happens

func (*Inode) IsDir

func (i *Inode) IsDir() bool

IsDir returns true if the inode is a directory inode.

func (*Inode) Mode

func (i *Inode) Mode() fs.FileMode

Mode returns the inode's mode as fs.FileMode

func (*Inode) OpenFile

func (ino *Inode) OpenFile(name string) fs.File

OpenFile returns a fs.File for a given inode. If the file is a directory, the returned object will implement fs.ReadDirFile. If it is a regular file it will also implement io.Seeker.

func (*Inode) ReadAt

func (i *Inode) ReadAt(p []byte, off int64) (int, error)
func (i *Inode) Readlink() ([]byte, error)

Readlink returns the inode's link

type Option added in v0.1.5

type Option func(sb *Superblock) error

func InodeOffset added in v0.1.5

func InodeOffset(inoOfft uint64) Option

type Superblock

type Superblock struct {
	Magic             uint32 // magic identifier
	InodeCnt          uint32 // number of inodes in filesystem
	ModTime           int32  // creation unix time as int32 (will stop working in 2038)
	BlockSize         uint32 // size of a single data block, must match 1<<BlockLog
	FragCount         uint32
	Comp              Compression // Compression used, usually GZip
	BlockLog          uint16
	Flags             Flags // squashfs flags
	IdCount           uint16
	VMajor            uint16
	VMinor            uint16
	RootInode         inodeRef // inode number/reference of root
	BytesUsed         uint64
	IdTableStart      uint64
	XattrIdTableStart uint64
	InodeTableStart   uint64
	DirTableStart     uint64
	FragTableStart    uint64
	ExportTableStart  uint64
	// contains filtered or unexported fields
}

Superblock is the main object representing a squashfs image, and exposes various information about the file. You can ignore most of these and use the object directly to access files/etc, or inspect various elements of the squashfs image.

func New

func New(fs io.ReaderAt, options ...Option) (*Superblock, error)

New returns a new instance of superblock for a given io.ReaderAt that can be used to access files inside squashfs.

func Open added in v0.1.5

func Open(file string, options ...Option) (*Superblock, error)

Open returns a new instance of superblock for a given file that can be used to access files inside squashfs. The file will be closed by the garbage collector or when Close() is called on the superblock.

func (*Superblock) Close added in v0.1.5

func (sb *Superblock) Close() error

Close will close the underlying file when a filesystem was open with Open()

func (*Superblock) FindInode added in v0.1.5

func (s *Superblock) FindInode(name string, followSymlinks bool) (*Inode, error)

FindInode returns the inode for a given path. If followSymlink is false and a symlink is found in the path, it will be followed anyway. If however the target file is a symlink, then its inode will be returned.

func (*Superblock) FindInodeUnder added in v1.0.0

func (s *Superblock) FindInodeUnder(cur *Inode, name string, followSymlinks bool) (*Inode, error)

FindInodeUnder returns an inode for a path starting at a given different inode

Note that it is not possible to access directories outside the given path, including using symlinks, as this effectively acts as a chroot. This can be useful to implement fs.Sub

func (*Superblock) GetInode

func (sb *Superblock) GetInode(ino uint64) (*Inode, error)

func (*Superblock) GetInodeRef

func (sb *Superblock) GetInodeRef(inor inodeRef) (*Inode, error)

func (*Superblock) Lstat added in v0.1.5

func (sb *Superblock) Lstat(name string) (fs.FileInfo, error)

Lstat will return stats for a given path inside the sqhashfs archive. If the target is a symbolic link, data on the link itself will be returned.

func (*Superblock) Open

func (sb *Superblock) Open(name string) (fs.File, error)

Open returns a fs.File for a given path, which can be a different object depending if the file is a regular file or a directory.

func (*Superblock) ReadDir

func (sb *Superblock) ReadDir(name string) ([]fs.DirEntry, error)

ReadDir implements fs.ReadDirFS and allows listing any directory inside the archive

func (sb *Superblock) Readlink(name string) (string, error)

Readlink allows reading the value of a symbolic link inside the archive.

func (*Superblock) SetInodeOffset

func (s *Superblock) SetInodeOffset(offt uint64)

SetInodeOffset allows setting the inode offset used for interacting with fuse. This can be safely ignored if not using fuse or when mounting only a single squashfs via fuse.

func (*Superblock) Stat

func (sb *Superblock) Stat(name string) (fs.FileInfo, error)

Stat will return stats for a given path inside the squashfs archive

func (*Superblock) UnmarshalBinary

func (s *Superblock) UnmarshalBinary(data []byte) error

UnmarshalBinary reads a binary header values into Superblock

type Type added in v0.1.5

type Type uint16
const (
	DirType Type = iota + 1
	FileType
	SymlinkType
	BlockDevType
	CharDevType
	FifoType
	SocketType
	XDirType
	XFileType
	XSymlinkType
	XBlockDevType
	XCharDevType
	XFifoType
	XSocketType
)

func (Type) Basic added in v0.1.5

func (t Type) Basic() Type

Basic returns the type as a basic type (ie. XDirType.Basic() == DirType)

func (Type) IsDir added in v0.1.5

func (t Type) IsDir() bool
func (t Type) IsSymlink() bool

func (Type) Mode added in v0.1.5

func (t Type) Mode() fs.FileMode

Mode returns a fs.FileMode for this type that contains no permissions, only the file's type

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL