| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899 |
- 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:]),
- }
- }
|