Skip to content

Commit

Permalink
iso9660 finalizeFileInfo contain enough info for rockridge extensions
Browse files Browse the repository at this point in the history
Signed-off-by: Avi Deitcher <[email protected]>
  • Loading branch information
deitch committed May 22, 2024
1 parent 13e86ff commit d9ec588
Show file tree
Hide file tree
Showing 3 changed files with 108 additions and 15 deletions.
2 changes: 1 addition & 1 deletion filesystem/iso9660/directoryentrysystemuseextension.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ type suspExtension interface {
Descriptor() string
Source() string
Version() uint8
GetFileExtensions(string, bool, bool) ([]directoryEntrySystemUseExtension, error)
GetFileExtensions(*finalizeFileInfo, bool, bool) ([]directoryEntrySystemUseExtension, error)
GetFinalizeExtensions(*finalizeFileInfo) ([]directoryEntrySystemUseExtension, error)
Relocatable() bool
Relocate(map[string]*finalizeFileInfo) ([]*finalizeFileInfo, map[string]*finalizeFileInfo, error)
Expand Down
82 changes: 69 additions & 13 deletions filesystem/iso9660/finalize.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"time"

"github.com/diskfs/go-diskfs/util"
"github.com/djherbis/times"
)

const (
Expand Down Expand Up @@ -41,6 +42,11 @@ type FinalizeOptions struct {
// IsDir() bool // abbreviation for Mode().IsDir()
// Sys() interface{} // underlying data source (can return nil)
//
// Also supports:
//
// AccessTime() time.Time
// ChangeTime() time.Time
//
//nolint:structcheck // keep unused members so that we can know their references
type finalizeFileInfo struct {
path string
Expand All @@ -56,6 +62,8 @@ type finalizeFileInfo struct {
size int64
mode os.FileMode
modTime time.Time
accessTime time.Time
changeTime time.Time
isDir bool
isRoot bool
bytes [][]byte
Expand All @@ -64,7 +72,10 @@ type finalizeFileInfo struct {
trueParent *finalizeFileInfo
trueChild *finalizeFileInfo
elToritoEntry *ElToritoEntry
content []byte
linkTarget string
// content in memory content of file. If this is anything other than nil, including a zero-length slice,
// then this content is used, rather than anything on disk.
content []byte
}

func (fi *finalizeFileInfo) Name() string {
Expand Down Expand Up @@ -100,6 +111,15 @@ func (fi *finalizeFileInfo) updateDepth(depth int) {
}
}
}
func (fi *finalizeFileInfo) AccessTime() time.Time {
return fi.accessTime
}
func (fi *finalizeFileInfo) ChangeTime() time.Time {
return fi.changeTime
}
func (fi *finalizeFileInfo) LinkTarget() string {
return fi.linkTarget
}

func (fi *finalizeFileInfo) toDirectoryEntry(fs *FileSystem, isSelf, isParent bool) (*directoryEntry, error) {
de := &directoryEntry{
Expand Down Expand Up @@ -127,7 +147,11 @@ func (fi *finalizeFileInfo) toDirectoryEntry(fs *FileSystem, isSelf, isParent bo
}
// add appropriate PX, TF, SL, NM extensions
for _, e := range fs.suspExtensions {
ext, err := e.GetFileExtensions(path.Join(fs.workspace, fi.path), isSelf, isParent)
var (
ext []directoryEntrySystemUseExtension
err error
)
ext, err = e.GetFileExtensions(fi, isSelf, isParent)
if err != nil {
return nil, fmt.Errorf("error getting extensions for %s at path %s: %v", e.ID(), fi.path, err)
}
Expand Down Expand Up @@ -467,14 +491,18 @@ func (fs *FileSystem) Finalize(options FinalizeOptions) error {
shortname, extension := calculateShortnameExtension(path.Base(catname))
// break down the catalog basename from the parent dir
catSize := int64(len(bootcat))
now := time.Now()
catEntry = &finalizeFileInfo{
content: bootcat,
size: catSize,
path: catname,
name: path.Base(catname),
shortname: shortname,
extension: extension,
blocks: calculateBlocks(catSize, fs.blocksize),
content: bootcat,
size: catSize,
path: catname,
name: path.Base(catname),
shortname: shortname,
extension: extension,
blocks: calculateBlocks(catSize, fs.blocksize),
modTime: now,
accessTime: now,
changeTime: now,
}
// make it the first file
files = append([]*finalizeFileInfo{catEntry}, files...)
Expand Down Expand Up @@ -601,8 +629,9 @@ func (fs *FileSystem) Finalize(options FinalizeOptions) error {
}()
for _, e := range files {
var (
from *os.File
copied int
from *os.File
copied int
bootTableSize int
)
writeAt := int64(e.location) * int64(blocksize)
if e.content == nil {
Expand Down Expand Up @@ -632,6 +661,7 @@ func (fs *FileSystem) Finalize(options FinalizeOptions) error {
return fmt.Errorf("failed to write 56 byte boot table to disk %s: %v", e.path, err)
}
copied += count
bootTableSize += count
// remainder of file
count, err = copyFileData(from, f, 64, writeAt+64, 0)
if err != nil {
Expand All @@ -644,7 +674,7 @@ func (fs *FileSystem) Finalize(options FinalizeOptions) error {
return fmt.Errorf("failed to copy file to disk %s: %v", e.path, err)
}
}
if copied != int(e.Size()) {
if copied != int(e.Size()+int64(bootTableSize)) {
return fmt.Errorf("error copying file %s to disk, copied %d bytes, expected %d", e.path, copied, e.Size())
}
} else {
Expand Down Expand Up @@ -832,7 +862,33 @@ func walkTree(workspace string) ([]*finalizeFileInfo, map[string]*finalizeFileIn
name = string([]byte{0x00})
shortname = name
}
entry = &finalizeFileInfo{path: fp, name: name, isDir: fi.IsDir(), isRoot: isRoot, modTime: fi.ModTime(), mode: fi.Mode(), size: fi.Size(), shortname: shortname}
actualPath := path.Join(workspace, fp)
t, err := times.Lstat(actualPath)
if err != nil {
return fmt.Errorf("could not get times information for %s: %w", actualPath, err)
}
mode := fi.Mode()
var target string
if fi.Mode()&os.ModeSymlink == os.ModeSymlink {
target, err = os.Readlink(actualPath)
if err != nil {
return fmt.Errorf("unable to read link for %s: %w", actualPath, err)
}
}

entry = &finalizeFileInfo{
path: fp,
name: name,
isDir: fi.IsDir(),
isRoot: isRoot,
modTime: fi.ModTime(),
accessTime: t.AccessTime(),
changeTime: t.ChangeTime(),
mode: mode,
size: fi.Size(),
shortname: shortname,
linkTarget: target,
}

// we will have to save it as its parent
parentDir := filepath.Dir(fp)
Expand Down
39 changes: 38 additions & 1 deletion filesystem/iso9660/rockridge.go
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ func (r *rockRidgeExtension) GetFilename(de *directoryEntry) (string, error) {
}
return name, nil
}
func (r *rockRidgeExtension) GetFileExtensions(fp string, isSelf, isParent bool) ([]directoryEntrySystemUseExtension, error) {
func (r *rockRidgeExtension) GetFileExtensionsOld(fp string, isSelf, isParent bool) ([]directoryEntrySystemUseExtension, error) {
// we always do PX, TF, NM, SL order
ret := []directoryEntrySystemUseExtension{}
// do not follow symlinks
Expand Down Expand Up @@ -148,6 +148,43 @@ func (r *rockRidgeExtension) GetFileExtensions(fp string, isSelf, isParent bool)
return ret, nil
}

func (r *rockRidgeExtension) GetFileExtensions(ffi *finalizeFileInfo, isSelf, isParent bool) ([]directoryEntrySystemUseExtension, error) {
// we always do PX, TF, NM, SL order
ret := []directoryEntrySystemUseExtension{}
// do not follow symlinks

// PX
nlink, uid, gid := statt(ffi)
mtime := ffi.ModTime()

ret = append(ret, rockRidgePosixAttributes{
mode: ffi.Mode(),
linkCount: nlink,
uid: uid,
gid: gid,
length: r.pxLength,
})
// TF
tf := rockRidgeTimestamps{longForm: false, stamps: []rockRidgeTimestamp{
{timestampType: rockRidgeTimestampModify, time: mtime},
{timestampType: rockRidgeTimestampAccess, time: ffi.AccessTime()},
{timestampType: rockRidgeTimestampAttribute, time: ffi.ChangeTime()},
}}

ret = append(ret, tf)
// NM
if !isSelf && !isParent {
ret = append(ret, rockRidgeName{name: ffi.Name()})
}
// SL
if ffi.Mode()&os.ModeSymlink == os.ModeSymlink {
// need the target if it is a symlink
ret = append(ret, rockRidgeSymlink{continued: false, name: ffi.LinkTarget()})
}

return ret, nil
}

func (r *rockRidgeExtension) GetFinalizeExtensions(fi *finalizeFileInfo) ([]directoryEntrySystemUseExtension, error) {
// we look for CL, PL, RE entries
ret := []directoryEntrySystemUseExtension{}
Expand Down

0 comments on commit d9ec588

Please sign in to comment.