mirror of
https://hubproxy.babadafafafafa.cn/https://github.com/yunionio/cloudpods.git
synced 2026-09-20 08:03:53 +08:00
100 lines
2.3 KiB
Go
100 lines
2.3 KiB
Go
package iso9660
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
)
|
|
|
|
/* The following types of Rock Ridge records are being handled in some way:
|
|
* - [X] PX (RR 4.1.1: POSIX file attributes)
|
|
* - [ ] PN (RR 4.1.2: POSIX device number)
|
|
* - [ ] SL (RR 4.1.3: symbolic link)
|
|
* - [x] NM (RR 4.1.4: alternate name)
|
|
* - [ ] CL (RR 4.1.5.1: child link)
|
|
* - [ ] PL (RR 4.1.5.2: parent link)
|
|
* - [ ] RE (RR 4.1.5.3: relocated directory)
|
|
* - [ ] TF (RR 4.1.6: time stamp(s) for a file)
|
|
* - [ ] SF (RR 4.1.7: file data in sparse file format)
|
|
*/
|
|
|
|
const (
|
|
RockRidgeIdentifier = "RRIP_1991A"
|
|
RockRidgeVersion = 1
|
|
)
|
|
|
|
type RockRidgeNameEntry struct {
|
|
Flags byte
|
|
Name string
|
|
}
|
|
|
|
func suspHasRockRidge(se SystemUseEntrySlice) (bool, error) {
|
|
extensions, err := se.GetExtensionRecords()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
for _, entry := range extensions {
|
|
if entry.Identifier == RockRidgeIdentifier && entry.Version == RockRidgeVersion {
|
|
return true, nil
|
|
}
|
|
}
|
|
|
|
return false, nil
|
|
}
|
|
|
|
func (s SystemUseEntrySlice) GetRockRidgeName() string {
|
|
var name string
|
|
|
|
for _, entry := range s {
|
|
// There is a continuation flag in the record, but we determine continuation
|
|
// by simply reading all NM entries.
|
|
if entry.Type() == "NM" {
|
|
nm := umarshalRockRidgeNameEntry(entry)
|
|
name += nm.Name
|
|
}
|
|
}
|
|
|
|
return name
|
|
}
|
|
|
|
func (s SystemUseEntrySlice) GetPosixAttr() (fs.FileMode, error) {
|
|
for _, entry := range s {
|
|
if entry.Type() == "PX" {
|
|
// BUG(kdomanski): If there are multiple RR PX entries (which is forbidden by the spec), the reader will use the first one.
|
|
return umarshalRockRidgeAttrEntry(entry)
|
|
}
|
|
}
|
|
|
|
return 0, fmt.Errorf("mandatory entry PX not found")
|
|
}
|
|
|
|
func umarshalRockRidgeAttrEntry(e SystemUseEntry) (fs.FileMode, error) {
|
|
rrMode, err := UnmarshalUint32LSBMSB(e.Data()[0:8])
|
|
if err != nil {
|
|
return 0, fmt.Errorf("unmarshall RR PX entry: %w", err)
|
|
}
|
|
|
|
S_IFLNK := (rrMode & 0170000) == 0120000
|
|
S_IFDIR := (rrMode & 0170000) == 0040000
|
|
|
|
mode := rrMode & uint32(fs.ModePerm) // UNIX permissions
|
|
|
|
if S_IFLNK {
|
|
mode |= uint32(os.ModeSymlink)
|
|
}
|
|
|
|
if S_IFDIR {
|
|
mode |= uint32(os.ModeDir)
|
|
}
|
|
|
|
return fs.FileMode(mode), nil
|
|
}
|
|
|
|
func umarshalRockRidgeNameEntry(e SystemUseEntry) *RockRidgeNameEntry {
|
|
return &RockRidgeNameEntry{
|
|
Flags: e.Data()[0],
|
|
Name: string(e.Data()[1:]),
|
|
}
|
|
}
|