e302d98665
Extracting files is threaded with goroutines. Extracting also sets the proper UID and GUID Made recursive children getting threaded with goroutines Decided I will allow wildcards in paths. Hasn't been implemented though. Fixed issues with ExtendedDirectory reading (I was using a uint16 instead of a uint32) I couldn't test basically any of this. somehow a for loop isn't incrementing. For seemingly no reason.
95 lines
2.0 KiB
Go
95 lines
2.0 KiB
Go
package directory
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/binary"
|
|
"io"
|
|
)
|
|
|
|
//Header is the header for a directory in the directory table
|
|
type Header struct {
|
|
Count uint32
|
|
InodeOffset uint32
|
|
InodeNumber uint32
|
|
}
|
|
|
|
//EntryInit is the values that can be easily decoded
|
|
type EntryInit struct {
|
|
Offset uint16
|
|
InodeOffset int16
|
|
Type uint16
|
|
NameSize uint16
|
|
}
|
|
|
|
//Entry is an entry in a directory.
|
|
type Entry struct {
|
|
Init EntryInit
|
|
Name string
|
|
Header *Header
|
|
}
|
|
|
|
//NewEntry creates a new directory entry
|
|
func NewEntry(rdr io.Reader) (Entry, error) {
|
|
var entry Entry
|
|
err := binary.Read(rdr, binary.LittleEndian, &entry.Init)
|
|
if err != nil {
|
|
return Entry{}, err
|
|
}
|
|
tmp := make([]byte, entry.Init.NameSize+1)
|
|
err = binary.Read(rdr, binary.LittleEndian, &tmp)
|
|
if err != nil {
|
|
return Entry{}, err
|
|
}
|
|
entry.Name = string(tmp)
|
|
return entry, err
|
|
}
|
|
|
|
//Directory is an entry in the directory table of a squashfs.
|
|
//Will only have multiple headers if there are more then 256 entries
|
|
type Directory struct {
|
|
Headers []Header
|
|
Entries []Entry
|
|
}
|
|
|
|
//NewDirectory reads the directory from rdr
|
|
func NewDirectory(base io.Reader, size uint32) (*Directory, error) {
|
|
var dir Directory
|
|
var err error
|
|
tmp := make([]byte, size)
|
|
base.Read(tmp)
|
|
rdr := bytes.NewBuffer(tmp)
|
|
for {
|
|
var hdr Header
|
|
err = binary.Read(rdr, binary.LittleEndian, &hdr)
|
|
if err == io.ErrUnexpectedEOF {
|
|
break
|
|
} else if err != nil {
|
|
return nil, err
|
|
}
|
|
hdr.Count++
|
|
headers := hdr.Count / 256
|
|
if hdr.Count%256 > 0 {
|
|
headers++
|
|
}
|
|
dir.Headers = append(dir.Headers, hdr)
|
|
for i := uint32(0); i < hdr.Count; i++ {
|
|
if i != 0 && i%256 == 0 {
|
|
var newHdr Header
|
|
err = binary.Read(rdr, binary.LittleEndian, &newHdr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
dir.Headers = append(dir.Headers, newHdr)
|
|
}
|
|
var ent Entry
|
|
ent, err = NewEntry(rdr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
ent.Header = &dir.Headers[len(dir.Headers)-1]
|
|
dir.Entries = append(dir.Entries, ent)
|
|
}
|
|
}
|
|
return &dir, nil
|
|
}
|