From e25847c90cf3c574e1024e83e0f8993cfc04c7d1 Mon Sep 17 00:00:00 2001 From: calluo Date: Wed, 2 Nov 2022 15:22:21 +0800 Subject: [PATCH] archive50 parse header, impl file redirection to get link file info --- archive50.go | 24 +++++++++++++++++++++++- reader.go | 9 +++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/archive50.go b/archive50.go index 1d8f850..1cd7837 100644 --- a/archive50.go +++ b/archive50.go @@ -47,6 +47,13 @@ const ( file5EncCheckPresent = 0x0001 // password check data is present file5EncUseMac = 0x0002 // use MAC instead of plain checksum + // file system redirection flags + file5UnixSymlink = 0x0001 + file5WindowsSymlink = 0x0002 + file5WindowsJunction = 0x0003 + file5HardLink = 0x0004 + file5FileCopy = 0x0005 + cacheSize50 = 4 maxPbkdf2Salt = 64 pwCheckSize = 8 @@ -250,6 +257,21 @@ func (a *archive50) parseFileEncryptionRecord(b readBuf, f *fileBlockHeader) err return nil } +// parseFileRedirectionRecord processes the file reddirection record from a file header +func (a *archive50) parseFileRedirectionRecord(b readBuf, f *fileBlockHeader) error { + types := b.uvarint() + if types&file5WindowsSymlink > 0 || types&file5UnixSymlink > 0 { + f.LinkType = TypeSymlink + } else if types&file5HardLink > 0 { + f.LinkType = TypeLink + } + // pass link target flags + b.uvarint() + lenName := int(b.uvarint()) + f.LinkName = string(b.bytes(lenName)) + return nil +} + func (a *archive50) parseFileHeader(h *blockHeader50) (*fileBlockHeader, error) { a.checksum.sum = nil a.checksum.key = nil @@ -324,7 +346,7 @@ func (a *archive50) parseFileHeader(h *blockHeader50) (*fileBlockHeader, error) _ = e.data.uvarint() // ignore flags field f.Version = int(e.data.uvarint()) case 5: - // TODO: redirection + err = a.parseFileRedirectionRecord(e.data, f) case 6: // TODO: owner } diff --git a/reader.go b/reader.go index 11adc4f..db9ab31 100644 --- a/reader.go +++ b/reader.go @@ -25,6 +25,13 @@ const ( maxPassword = 128 ) +const ( + // Type '0' indicates a regular file. + TypeReg = '0' + TypeLink = '1' // Hard link + TypeSymlink = '2' // Symbolic link +) + var ( errShortFile = errors.New("rardecode: decoded file too short") errInvalidFileBlock = errors.New("rardecode: invalid file block") @@ -105,6 +112,8 @@ type FileHeader struct { CreationTime time.Time // creation time (non-zero if set) AccessTime time.Time // access time (non-zero if set) Version int // file version + LinkType byte // + LinkName string // link name } // Mode returns an os.FileMode for the file, calculated from the Attributes field.