diff --git a/internal/fs/ea_windows_test.go b/internal/fs/ea_windows_test.go index 74afd7aa5..e474a3735 100644 --- a/internal/fs/ea_windows_test.go +++ b/internal/fs/ea_windows_test.go @@ -142,7 +142,7 @@ func TestSetGetFileEA(t *testing.T) { testFilePath, testFile := setupTestFile(t) testEAs := generateTestEAs(t, 3, testFilePath) fileHandle := openFile(t, testFilePath, windows.FILE_ATTRIBUTE_NORMAL) - defer closeFileHandle(t, testFilePath, testFile, fileHandle) + defer testCloseFileHandle(t, testFilePath, testFile, fileHandle) testSetGetEA(t, testFilePath, fileHandle, testEAs) } @@ -154,7 +154,7 @@ func TestSetGetFolderEA(t *testing.T) { testEAs := generateTestEAs(t, 3, testFolderPath) fileHandle := openFile(t, testFolderPath, windows.FILE_ATTRIBUTE_NORMAL|windows.FILE_FLAG_BACKUP_SEMANTICS) - defer closeFileHandle(t, testFolderPath, nil, fileHandle) + defer testCloseFileHandle(t, testFolderPath, nil, fileHandle) testSetGetEA(t, testFolderPath, fileHandle, testEAs) } @@ -212,7 +212,7 @@ func openFile(t *testing.T, path string, attributes uint32) windows.Handle { return fileHandle } -func closeFileHandle(t *testing.T, testfilePath string, testFile *os.File, handle windows.Handle) { +func testCloseFileHandle(t *testing.T, testfilePath string, testFile *os.File, handle windows.Handle) { if testFile != nil { err := testFile.Close() if err != nil { diff --git a/internal/restic/node.go b/internal/restic/node.go index 6afdff64a..c9c68cbee 100644 --- a/internal/restic/node.go +++ b/internal/restic/node.go @@ -150,7 +150,7 @@ func NodeFromFileInfo(path string, fi os.FileInfo, ignoreXattrListError bool) (* node.Size = uint64(fi.Size()) } - err := node.fillExtra(path, fi, ignoreXattrListError) + err := nodeFillExtra(node, path, fi, ignoreXattrListError) return node, err } @@ -187,33 +187,33 @@ func (node Node) GetExtendedAttribute(a string) []byte { return nil } -// CreateAt creates the node at the given path but does NOT restore node meta data. -func (node *Node) CreateAt(ctx context.Context, path string, repo BlobLoader) error { +// NodeCreateAt creates the node at the given path but does NOT restore node meta data. +func NodeCreateAt(ctx context.Context, node *Node, path string, repo BlobLoader) error { debug.Log("create node %v at %v", node.Name, path) switch node.Type { case "dir": - if err := node.createDirAt(path); err != nil { + if err := nodeCreateDirAt(node, path); err != nil { return err } case "file": - if err := node.createFileAt(ctx, path, repo); err != nil { + if err := nodeCreateFileAt(ctx, node, path, repo); err != nil { return err } case "symlink": - if err := node.createSymlinkAt(path); err != nil { + if err := nodeCreateSymlinkAt(node, path); err != nil { return err } case "dev": - if err := node.createDevAt(path); err != nil { + if err := nodeCreateDevAt(node, path); err != nil { return err } case "chardev": - if err := node.createCharDevAt(path); err != nil { + if err := nodeCreateCharDevAt(node, path); err != nil { return err } case "fifo": - if err := node.createFifoAt(path); err != nil { + if err := nodeCreateFifoAt(path); err != nil { return err } case "socket": @@ -225,9 +225,9 @@ func (node *Node) CreateAt(ctx context.Context, path string, repo BlobLoader) er return nil } -// RestoreMetadata restores node metadata -func (node Node) RestoreMetadata(path string, warn func(msg string)) error { - err := node.restoreMetadata(path, warn) +// NodeRestoreMetadata restores node metadata +func NodeRestoreMetadata(node *Node, path string, warn func(msg string)) error { + err := nodeRestoreMetadata(node, path, warn) if err != nil { // It is common to have permission errors for folders like /home // unless you're running as root, so ignore those. @@ -242,28 +242,28 @@ func (node Node) RestoreMetadata(path string, warn func(msg string)) error { return err } -func (node Node) restoreMetadata(path string, warn func(msg string)) error { +func nodeRestoreMetadata(node *Node, path string, warn func(msg string)) error { var firsterr error if err := lchown(path, int(node.UID), int(node.GID)); err != nil { firsterr = errors.WithStack(err) } - if err := node.restoreExtendedAttributes(path); err != nil { + if err := nodeRestoreExtendedAttributes(node, path); err != nil { debug.Log("error restoring extended attributes for %v: %v", path, err) if firsterr == nil { firsterr = err } } - if err := node.restoreGenericAttributes(path, warn); err != nil { + if err := nodeRestoreGenericAttributes(node, path, warn); err != nil { debug.Log("error restoring generic attributes for %v: %v", path, err) if firsterr == nil { firsterr = err } } - if err := node.RestoreTimestamps(path); err != nil { + if err := NodeRestoreTimestamps(node, path); err != nil { debug.Log("error restoring timestamps for %v: %v", path, err) if firsterr == nil { firsterr = err @@ -284,14 +284,14 @@ func (node Node) restoreMetadata(path string, warn func(msg string)) error { return firsterr } -func (node Node) RestoreTimestamps(path string) error { +func NodeRestoreTimestamps(node *Node, path string) error { var utimes = [...]syscall.Timespec{ syscall.NsecToTimespec(node.AccessTime.UnixNano()), syscall.NsecToTimespec(node.ModTime.UnixNano()), } if node.Type == "symlink" { - return node.restoreSymlinkTimestamps(path, utimes) + return nodeRestoreSymlinkTimestamps(path, utimes) } if err := syscall.UtimesNano(path, utimes[:]); err != nil { @@ -301,7 +301,7 @@ func (node Node) RestoreTimestamps(path string) error { return nil } -func (node Node) createDirAt(path string) error { +func nodeCreateDirAt(node *Node, path string) error { err := fs.Mkdir(path, node.Mode) if err != nil && !os.IsExist(err) { return errors.WithStack(err) @@ -310,13 +310,13 @@ func (node Node) createDirAt(path string) error { return nil } -func (node Node) createFileAt(ctx context.Context, path string, repo BlobLoader) error { +func nodeCreateFileAt(ctx context.Context, node *Node, path string, repo BlobLoader) error { f, err := fs.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0600) if err != nil { return errors.WithStack(err) } - err = node.writeNodeContent(ctx, repo, f) + err = nodeWriteNodeContent(ctx, node, repo, f) closeErr := f.Close() if err != nil { @@ -330,7 +330,7 @@ func (node Node) createFileAt(ctx context.Context, path string, repo BlobLoader) return nil } -func (node Node) writeNodeContent(ctx context.Context, repo BlobLoader, f *os.File) error { +func nodeWriteNodeContent(ctx context.Context, node *Node, repo BlobLoader, f *os.File) error { var buf []byte for _, id := range node.Content { buf, err := repo.LoadBlob(ctx, DataBlob, id, buf) @@ -347,7 +347,7 @@ func (node Node) writeNodeContent(ctx context.Context, repo BlobLoader, f *os.Fi return nil } -func (node Node) createSymlinkAt(path string) error { +func nodeCreateSymlinkAt(node *Node, path string) error { if err := fs.Symlink(node.LinkTarget, path); err != nil { return errors.WithStack(err) } @@ -355,15 +355,15 @@ func (node Node) createSymlinkAt(path string) error { return nil } -func (node *Node) createDevAt(path string) error { +func nodeCreateDevAt(node *Node, path string) error { return mknod(path, syscall.S_IFBLK|0600, node.Device) } -func (node *Node) createCharDevAt(path string) error { +func nodeCreateCharDevAt(node *Node, path string) error { return mknod(path, syscall.S_IFCHR|0600, node.Device) } -func (node *Node) createFifoAt(path string) error { +func nodeCreateFifoAt(path string) error { return mkfifo(path, 0600) } @@ -601,7 +601,7 @@ func deepEqual(map1, map2 map[GenericAttributeType]json.RawMessage) bool { return true } -func (node *Node) fillUser(stat *statT) { +func nodeFillUser(node *Node, stat *statT) { uid, gid := stat.uid(), stat.gid() node.UID, node.GID = uid, gid node.User = lookupUsername(uid) @@ -662,7 +662,7 @@ func lookupGroup(gid uint32) string { return group } -func (node *Node) fillExtra(path string, fi os.FileInfo, ignoreXattrListError bool) error { +func nodeFillExtra(node *Node, path string, fi os.FileInfo, ignoreXattrListError bool) error { stat, ok := toStatT(fi.Sys()) if !ok { // fill minimal info with current values for uid, gid @@ -675,9 +675,9 @@ func (node *Node) fillExtra(path string, fi os.FileInfo, ignoreXattrListError bo node.Inode = uint64(stat.ino()) node.DeviceID = uint64(stat.dev()) - node.fillTimes(stat) + nodeFillTimes(node, stat) - node.fillUser(stat) + nodeFillUser(node, stat) switch node.Type { case "file": @@ -703,10 +703,10 @@ func (node *Node) fillExtra(path string, fi os.FileInfo, ignoreXattrListError bo return errors.Errorf("unsupported file type %q", node.Type) } - allowExtended, err := node.fillGenericAttributes(path, fi, stat) + allowExtended, err := nodeFillGenericAttributes(node, path, fi, stat) if allowExtended { // Skip processing ExtendedAttributes if allowExtended is false. - err = errors.CombineErrors(err, node.fillExtendedAttributes(path, ignoreXattrListError)) + err = errors.CombineErrors(err, nodeFillExtendedAttributes(node, path, ignoreXattrListError)) } return err } @@ -715,7 +715,7 @@ func mkfifo(path string, mode uint32) (err error) { return mknod(path, mode|syscall.S_IFIFO, 0) } -func (node *Node) fillTimes(stat *statT) { +func nodeFillTimes(node *Node, stat *statT) { ctim := stat.ctim() atim := stat.atim() node.ChangeTime = time.Unix(ctim.Unix()) @@ -746,11 +746,11 @@ func handleUnknownGenericAttributeFound(genericAttributeType GenericAttributeTyp } } -// handleAllUnknownGenericAttributesFound performs validations for all generic attributes in the node. +// HandleAllUnknownGenericAttributesFound performs validations for all generic attributes of a node. // This is not used on windows currently because windows has handling for generic attributes. // nolint:unused -func (node Node) handleAllUnknownGenericAttributesFound(warn func(msg string)) error { - for name := range node.GenericAttributes { +func HandleAllUnknownGenericAttributesFound(attributes map[GenericAttributeType]json.RawMessage, warn func(msg string)) error { + for name := range attributes { handleUnknownGenericAttributeFound(name, warn) } return nil @@ -770,9 +770,8 @@ func checkGenericAttributeNameNotHandledAndPut(value GenericAttributeType) bool // The functions below are common helper functions which can be used for generic attributes support // across different OS. -// genericAttributesToOSAttrs gets the os specific attribute from the generic attribute using reflection -// nolint:unused -func genericAttributesToOSAttrs(attrs map[GenericAttributeType]json.RawMessage, attributeType reflect.Type, attributeValuePtr *reflect.Value, keyPrefix string) (unknownAttribs []GenericAttributeType, err error) { +// GenericAttributesToOSAttrs gets the os specific attribute from the generic attribute using reflection +func GenericAttributesToOSAttrs(attrs map[GenericAttributeType]json.RawMessage, attributeType reflect.Type, attributeValuePtr *reflect.Value, keyPrefix string) (unknownAttribs []GenericAttributeType, err error) { attributeValue := *attributeValuePtr for key, rawMsg := range attrs { @@ -796,20 +795,17 @@ func genericAttributesToOSAttrs(attrs map[GenericAttributeType]json.RawMessage, } // getFQKey gets the fully qualified key for the field -// nolint:unused func getFQKey(field reflect.StructField, keyPrefix string) GenericAttributeType { return GenericAttributeType(fmt.Sprintf("%s.%s", keyPrefix, field.Tag.Get("generic"))) } // getFQKeyByIndex gets the fully qualified key for the field index -// nolint:unused func getFQKeyByIndex(attributeType reflect.Type, index int, keyPrefix string) GenericAttributeType { return getFQKey(attributeType.Field(index), keyPrefix) } -// osAttrsToGenericAttributes gets the generic attribute from the os specific attribute using reflection -// nolint:unused -func osAttrsToGenericAttributes(attributeType reflect.Type, attributeValuePtr *reflect.Value, keyPrefix string) (attrs map[GenericAttributeType]json.RawMessage, err error) { +// OSAttrsToGenericAttributes gets the generic attribute from the os specific attribute using reflection +func OSAttrsToGenericAttributes(attributeType reflect.Type, attributeValuePtr *reflect.Value, keyPrefix string) (attrs map[GenericAttributeType]json.RawMessage, err error) { attributeValue := *attributeValuePtr attrs = make(map[GenericAttributeType]json.RawMessage) diff --git a/internal/restic/node_aix.go b/internal/restic/node_aix.go index 32f63af15..4cd279973 100644 --- a/internal/restic/node_aix.go +++ b/internal/restic/node_aix.go @@ -8,7 +8,7 @@ import ( "syscall" ) -func (node Node) restoreSymlinkTimestamps(_ string, _ [2]syscall.Timespec) error { +func nodeRestoreSymlinkTimestamps(_ string, _ [2]syscall.Timespec) error { return nil } @@ -23,13 +23,13 @@ func (s statT) atim() syscall.Timespec { return toTimespec(s.Atim) } func (s statT) mtim() syscall.Timespec { return toTimespec(s.Mtim) } func (s statT) ctim() syscall.Timespec { return toTimespec(s.Ctim) } -// restoreExtendedAttributes is a no-op on AIX. -func (node Node) restoreExtendedAttributes(_ string) error { +// nodeRestoreExtendedAttributes is a no-op on AIX. +func nodeRestoreExtendedAttributes(_ *Node, _ string) error { return nil } -// fillExtendedAttributes is a no-op on AIX. -func (node *Node) fillExtendedAttributes(_ string, _ bool) error { +// nodeFillExtendedAttributes is a no-op on AIX. +func nodeFillExtendedAttributes(_ *Node, _ string, _ bool) error { return nil } @@ -38,12 +38,12 @@ func IsListxattrPermissionError(_ error) bool { return false } -// restoreGenericAttributes is no-op on AIX. -func (node *Node) restoreGenericAttributes(_ string, warn func(msg string)) error { - return node.handleAllUnknownGenericAttributesFound(warn) +// nodeRestoreGenericAttributes is no-op on AIX. +func nodeRestoreGenericAttributes(node *Node, _ string, warn func(msg string)) error { + return HandleAllUnknownGenericAttributesFound(node.GenericAttributes, warn) } -// fillGenericAttributes is a no-op on AIX. -func (node *Node) fillGenericAttributes(_ string, _ os.FileInfo, _ *statT) (allowExtended bool, err error) { +// nodeFillGenericAttributes is a no-op on AIX. +func nodeFillGenericAttributes(_ *Node, _ string, _ os.FileInfo, _ *statT) (allowExtended bool, err error) { return true, nil } diff --git a/internal/restic/node_darwin.go b/internal/restic/node_darwin.go index 803aa68e5..099007e07 100644 --- a/internal/restic/node_darwin.go +++ b/internal/restic/node_darwin.go @@ -2,7 +2,7 @@ package restic import "syscall" -func (node Node) restoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { +func nodeRestoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { return nil } diff --git a/internal/restic/node_freebsd.go b/internal/restic/node_freebsd.go index 34d5b272c..6d2dd1d98 100644 --- a/internal/restic/node_freebsd.go +++ b/internal/restic/node_freebsd.go @@ -5,7 +5,7 @@ package restic import "syscall" -func (node Node) restoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { +func nodeRestoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { return nil } diff --git a/internal/restic/node_linux.go b/internal/restic/node_linux.go index 85a363830..6311a224b 100644 --- a/internal/restic/node_linux.go +++ b/internal/restic/node_linux.go @@ -10,7 +10,7 @@ import ( "github.com/restic/restic/internal/fs" ) -func (node Node) restoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { +func nodeRestoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { dir, err := fs.Open(filepath.Dir(path)) if err != nil { return errors.WithStack(err) diff --git a/internal/restic/node_netbsd.go b/internal/restic/node_netbsd.go index 0fe46a3f2..a53412afb 100644 --- a/internal/restic/node_netbsd.go +++ b/internal/restic/node_netbsd.go @@ -5,7 +5,7 @@ import ( "syscall" ) -func (node Node) restoreSymlinkTimestamps(_ string, _ [2]syscall.Timespec) error { +func nodeRestoreSymlinkTimestamps(_ string, _ [2]syscall.Timespec) error { return nil } @@ -13,13 +13,13 @@ func (s statT) atim() syscall.Timespec { return s.Atimespec } func (s statT) mtim() syscall.Timespec { return s.Mtimespec } func (s statT) ctim() syscall.Timespec { return s.Ctimespec } -// restoreExtendedAttributes is a no-op on netbsd. -func (node Node) restoreExtendedAttributes(_ string) error { +// nodeRestoreExtendedAttributes is a no-op on netbsd. +func nodeRestoreExtendedAttributes(_ *Node, _ string) error { return nil } -// fillExtendedAttributes is a no-op on netbsd. -func (node *Node) fillExtendedAttributes(_ string, _ bool) error { +// nodeFillExtendedAttributes is a no-op on netbsd. +func nodeFillExtendedAttributes(_ *Node, _ string, _ bool) error { return nil } @@ -28,12 +28,12 @@ func IsListxattrPermissionError(_ error) bool { return false } -// restoreGenericAttributes is no-op on netbsd. -func (node *Node) restoreGenericAttributes(_ string, warn func(msg string)) error { - return node.handleAllUnknownGenericAttributesFound(warn) +// nodeRestoreGenericAttributes is no-op on netbsd. +func nodeRestoreGenericAttributes(node *Node, _ string, warn func(msg string)) error { + return HandleAllUnknownGenericAttributesFound(node.GenericAttributes, warn) } -// fillGenericAttributes is a no-op on netbsd. -func (node *Node) fillGenericAttributes(_ string, _ os.FileInfo, _ *statT) (allowExtended bool, err error) { +// nodeFillGenericAttributes is a no-op on netbsd. +func nodeFillGenericAttributes(_ *Node, _ string, _ os.FileInfo, _ *statT) (allowExtended bool, err error) { return true, nil } diff --git a/internal/restic/node_openbsd.go b/internal/restic/node_openbsd.go index 71841f59f..bbba89f2c 100644 --- a/internal/restic/node_openbsd.go +++ b/internal/restic/node_openbsd.go @@ -5,7 +5,7 @@ import ( "syscall" ) -func (node Node) restoreSymlinkTimestamps(_ string, _ [2]syscall.Timespec) error { +func nodeRestoreSymlinkTimestamps(_ string, _ [2]syscall.Timespec) error { return nil } @@ -13,13 +13,13 @@ func (s statT) atim() syscall.Timespec { return s.Atim } func (s statT) mtim() syscall.Timespec { return s.Mtim } func (s statT) ctim() syscall.Timespec { return s.Ctim } -// restoreExtendedAttributes is a no-op on openbsd. -func (node Node) restoreExtendedAttributes(_ string) error { +// nodeRestoreExtendedAttributes is a no-op on openbsd. +func nodeRestoreExtendedAttributes(_ *Node, _ string) error { return nil } -// fillExtendedAttributes is a no-op on openbsd. -func (node *Node) fillExtendedAttributes(_ string, _ bool) error { +// nodeFillExtendedAttributes is a no-op on openbsd. +func nodeFillExtendedAttributes(_ *Node, _ string, _ bool) error { return nil } @@ -28,12 +28,12 @@ func IsListxattrPermissionError(_ error) bool { return false } -// restoreGenericAttributes is no-op on openbsd. -func (node *Node) restoreGenericAttributes(_ string, warn func(msg string)) error { - return node.handleAllUnknownGenericAttributesFound(warn) +// nodeRestoreGenericAttributes is no-op on openbsd. +func nodeRestoreGenericAttributes(node *Node, _ string, warn func(msg string)) error { + return HandleAllUnknownGenericAttributesFound(node.GenericAttributes, warn) } // fillGenericAttributes is a no-op on openbsd. -func (node *Node) fillGenericAttributes(_ string, _ os.FileInfo, _ *statT) (allowExtended bool, err error) { +func nodeFillGenericAttributes(_ *Node, _ string, _ os.FileInfo, _ *statT) (allowExtended bool, err error) { return true, nil } diff --git a/internal/restic/node_solaris.go b/internal/restic/node_solaris.go index c9d03f9c2..114d11766 100644 --- a/internal/restic/node_solaris.go +++ b/internal/restic/node_solaris.go @@ -2,7 +2,7 @@ package restic import "syscall" -func (node Node) restoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { +func nodeRestoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { return nil } diff --git a/internal/restic/node_test.go b/internal/restic/node_test.go index ab7f66e5b..7258b5429 100644 --- a/internal/restic/node_test.go +++ b/internal/restic/node_test.go @@ -245,8 +245,8 @@ func TestNodeRestoreAt(t *testing.T) { } else { nodePath = filepath.Join(tempdir, test.Name) } - rtest.OK(t, test.CreateAt(context.TODO(), nodePath, nil)) - rtest.OK(t, test.RestoreMetadata(nodePath, func(msg string) { rtest.OK(t, fmt.Errorf("Warning triggered for path: %s: %s", nodePath, msg)) })) + rtest.OK(t, NodeCreateAt(context.TODO(), &test, nodePath, nil)) + rtest.OK(t, NodeRestoreMetadata(&test, nodePath, func(msg string) { rtest.OK(t, fmt.Errorf("Warning triggered for path: %s: %s", nodePath, msg)) })) fi, err := os.Lstat(nodePath) rtest.OK(t, err) @@ -402,10 +402,10 @@ func TestSymlinkSerializationFormat(t *testing.T) { func TestNodeRestoreMetadataError(t *testing.T) { tempdir := t.TempDir() - node := nodeTests[0] + node := &nodeTests[0] nodePath := filepath.Join(tempdir, node.Name) // This will fail because the target file does not exist - err := node.RestoreMetadata(nodePath, func(msg string) { rtest.OK(t, fmt.Errorf("Warning triggered for path: %s: %s", nodePath, msg)) }) + err := NodeRestoreMetadata(node, nodePath, func(msg string) { rtest.OK(t, fmt.Errorf("Warning triggered for path: %s: %s", nodePath, msg)) }) test.Assert(t, errors.Is(err, os.ErrNotExist), "failed for an unexpected reason") } diff --git a/internal/restic/node_windows.go b/internal/restic/node_windows.go index bce01ccad..3f836ae61 100644 --- a/internal/restic/node_windows.go +++ b/internal/restic/node_windows.go @@ -56,7 +56,7 @@ func lchown(_ string, _ int, _ int) (err error) { } // restoreSymlinkTimestamps restores timestamps for symlinks -func (node Node) restoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { +func nodeRestoreSymlinkTimestamps(path string, utimes [2]syscall.Timespec) error { // tweaked version of UtimesNano from go/src/syscall/syscall_windows.go pathp, e := syscall.UTF16PtrFromString(path) if e != nil { @@ -82,7 +82,7 @@ func (node Node) restoreSymlinkTimestamps(path string, utimes [2]syscall.Timespe } // restore extended attributes for windows -func (node Node) restoreExtendedAttributes(path string) (err error) { +func nodeRestoreExtendedAttributes(node *Node, path string) (err error) { count := len(node.ExtendedAttributes) if count > 0 { eas := make([]fs.ExtendedAttribute, count) @@ -97,7 +97,7 @@ func (node Node) restoreExtendedAttributes(path string) (err error) { } // fill extended attributes in the node. This also includes the Generic attributes for windows. -func (node *Node) fillExtendedAttributes(path string, _ bool) (err error) { +func nodeFillExtendedAttributes(node *Node, path string, _ bool) (err error) { var fileHandle windows.Handle if fileHandle, err = fs.OpenHandleForEA(node.Type, path, false); fileHandle == 0 { return nil @@ -210,7 +210,7 @@ func (s statT) ctim() syscall.Timespec { } // restoreGenericAttributes restores generic attributes for Windows -func (node Node) restoreGenericAttributes(path string, warn func(msg string)) (err error) { +func nodeRestoreGenericAttributes(node *Node, path string, warn func(msg string)) (err error) { if len(node.GenericAttributes) == 0 { return nil } @@ -242,7 +242,7 @@ func (node Node) restoreGenericAttributes(path string, warn func(msg string)) (e // genericAttributesToWindowsAttrs converts the generic attributes map to a WindowsAttributes and also returns a string of unknown attributes that it could not convert. func genericAttributesToWindowsAttrs(attrs map[GenericAttributeType]json.RawMessage) (windowsAttributes WindowsAttributes, unknownAttribs []GenericAttributeType, err error) { waValue := reflect.ValueOf(&windowsAttributes).Elem() - unknownAttribs, err = genericAttributesToOSAttrs(attrs, reflect.TypeOf(windowsAttributes), &waValue, "windows") + unknownAttribs, err = GenericAttributesToOSAttrs(attrs, reflect.TypeOf(windowsAttributes), &waValue, "windows") return windowsAttributes, unknownAttribs, err } @@ -361,11 +361,11 @@ func decryptFile(pathPointer *uint16) error { return nil } -// fillGenericAttributes fills in the generic attributes for windows like File Attributes, +// nodeFillGenericAttributes fills in the generic attributes for windows like File Attributes, // Created time and Security Descriptors. // It also checks if the volume supports extended attributes and stores the result in a map // so that it does not have to be checked again for subsequent calls for paths in the same volume. -func (node *Node) fillGenericAttributes(path string, fi os.FileInfo, stat *statT) (allowExtended bool, err error) { +func nodeFillGenericAttributes(node *Node, path string, fi os.FileInfo, stat *statT) (allowExtended bool, err error) { if strings.Contains(filepath.Base(path), ":") { // Do not process for Alternate Data Streams in Windows // Also do not allow processing of extended attributes for ADS. @@ -499,7 +499,7 @@ func prepareVolumeName(path string) (volumeName string, err error) { func WindowsAttrsToGenericAttributes(windowsAttributes WindowsAttributes) (attrs map[GenericAttributeType]json.RawMessage, err error) { // Get the value of the WindowsAttributes windowsAttributesValue := reflect.ValueOf(windowsAttributes) - return osAttrsToGenericAttributes(reflect.TypeOf(windowsAttributes), &windowsAttributesValue, runtime.GOOS) + return OSAttrsToGenericAttributes(reflect.TypeOf(windowsAttributes), &windowsAttributesValue, runtime.GOOS) } // getCreationTime gets the value for the WindowsAttribute CreationTime in a windows specific time format. diff --git a/internal/restic/node_windows_test.go b/internal/restic/node_windows_test.go index 6ba25559b..e78c8cb96 100644 --- a/internal/restic/node_windows_test.go +++ b/internal/restic/node_windows_test.go @@ -42,7 +42,7 @@ func testRestoreSecurityDescriptor(t *testing.T, sd string, tempDir, fileType, f expectedNode := getNode(fileName, fileType, genericAttributes) // Restore the file/dir and restore the meta data including the security descriptors. - testPath, node := restoreAndGetNode(t, tempDir, expectedNode, false) + testPath, node := restoreAndGetNode(t, tempDir, &expectedNode, false) // Get the security descriptor from the node constructed from the file info of the restored path. sdByteFromRestoredNode := getWindowsAttr(t, testPath, node).SecurityDescriptor @@ -186,7 +186,7 @@ func runGenericAttributesTest(t *testing.T, tempDir string, genericAttributeName func runGenericAttributesTestForNodes(t *testing.T, expectedNodes []Node, tempDir string, genericAttr GenericAttributeType, genericAttributeExpected WindowsAttributes, warningExpected bool) { for _, testNode := range expectedNodes { - testPath, node := restoreAndGetNode(t, tempDir, testNode, warningExpected) + testPath, node := restoreAndGetNode(t, tempDir, &testNode, warningExpected) rawMessage := node.GenericAttributes[genericAttr] genericAttrsExpected, err := WindowsAttrsToGenericAttributes(genericAttributeExpected) test.OK(t, err) @@ -195,7 +195,7 @@ func runGenericAttributesTestForNodes(t *testing.T, expectedNodes []Node, tempDi } } -func restoreAndGetNode(t *testing.T, tempDir string, testNode Node, warningExpected bool) (string, *Node) { +func restoreAndGetNode(t *testing.T, tempDir string, testNode *Node, warningExpected bool) (string, *Node) { testPath := filepath.Join(tempDir, "001", testNode.Name) err := os.MkdirAll(filepath.Dir(testPath), testNode.Mode) test.OK(t, errors.Wrapf(err, "Failed to create parent directories for: %s", testPath)) @@ -211,7 +211,7 @@ func restoreAndGetNode(t *testing.T, tempDir string, testNode Node, warningExpec test.OK(t, errors.Wrapf(err, "Failed to create test directory: %s", testPath)) } - err = testNode.RestoreMetadata(testPath, func(msg string) { + err = NodeRestoreMetadata(testNode, testPath, func(msg string) { if warningExpected { test.Assert(t, warningExpected, "Warning triggered as expected: %s", msg) } else { @@ -260,7 +260,7 @@ func TestNewGenericAttributeType(t *testing.T) { }, } for _, testNode := range expectedNodes { - testPath, node := restoreAndGetNode(t, tempDir, testNode, true) + testPath, node := restoreAndGetNode(t, tempDir, &testNode, true) _, ua, err := genericAttributesToWindowsAttrs(node.GenericAttributes) test.OK(t, err) // Since this GenericAttribute is unknown to this version of the software, it will not get set on the file. @@ -296,7 +296,7 @@ func TestRestoreExtendedAttributes(t *testing.T) { }, } for _, testNode := range expectedNodes { - testPath, node := restoreAndGetNode(t, tempDir, testNode, false) + testPath, node := restoreAndGetNode(t, tempDir, &testNode, false) var handle windows.Handle var err error diff --git a/internal/restic/node_xattr.go b/internal/restic/node_xattr.go index 5a5a253d9..062ef4345 100644 --- a/internal/restic/node_xattr.go +++ b/internal/restic/node_xattr.go @@ -64,17 +64,17 @@ func handleXattrErr(err error) error { } } -// restoreGenericAttributes is no-op. -func (node *Node) restoreGenericAttributes(_ string, warn func(msg string)) error { - return node.handleAllUnknownGenericAttributesFound(warn) +// nodeRestoreGenericAttributes is no-op. +func nodeRestoreGenericAttributes(node *Node, _ string, warn func(msg string)) error { + return HandleAllUnknownGenericAttributesFound(node.GenericAttributes, warn) } -// fillGenericAttributes is a no-op. -func (node *Node) fillGenericAttributes(_ string, _ os.FileInfo, _ *statT) (allowExtended bool, err error) { +// nodeFillGenericAttributes is a no-op. +func nodeFillGenericAttributes(_ *Node, _ string, _ os.FileInfo, _ *statT) (allowExtended bool, err error) { return true, nil } -func (node Node) restoreExtendedAttributes(path string) error { +func nodeRestoreExtendedAttributes(node *Node, path string) error { expectedAttrs := map[string]struct{}{} for _, attr := range node.ExtendedAttributes { err := setxattr(path, attr.Name, attr.Value) @@ -101,7 +101,7 @@ func (node Node) restoreExtendedAttributes(path string) error { return nil } -func (node *Node) fillExtendedAttributes(path string, ignoreListError bool) error { +func nodeFillExtendedAttributes(node *Node, path string, ignoreListError bool) error { xattrs, err := listxattr(path) debug.Log("fillExtendedAttributes(%v) %v %v", path, xattrs, err) if err != nil { diff --git a/internal/restic/node_xattr_all_test.go b/internal/restic/node_xattr_all_test.go index 56ce5e286..30d29a6ed 100644 --- a/internal/restic/node_xattr_all_test.go +++ b/internal/restic/node_xattr_all_test.go @@ -21,18 +21,18 @@ func setAndVerifyXattr(t *testing.T, file string, attrs []ExtendedAttribute) { } } - node := Node{ + node := &Node{ Type: "file", ExtendedAttributes: attrs, } - rtest.OK(t, node.restoreExtendedAttributes(file)) + rtest.OK(t, nodeRestoreExtendedAttributes(node, file)) - nodeActual := Node{ + nodeActual := &Node{ Type: "file", } - rtest.OK(t, nodeActual.fillExtendedAttributes(file, false)) + rtest.OK(t, nodeFillExtendedAttributes(nodeActual, file, false)) - rtest.Assert(t, nodeActual.sameExtendedAttributes(node), "xattr mismatch got %v expected %v", nodeActual.ExtendedAttributes, node.ExtendedAttributes) + rtest.Assert(t, nodeActual.Equals(*node), "xattr mismatch got %v expected %v", nodeActual.ExtendedAttributes, node.ExtendedAttributes) } func TestOverwriteXattr(t *testing.T) { diff --git a/internal/restorer/restorer.go b/internal/restorer/restorer.go index 0e30b82f8..31157c979 100644 --- a/internal/restorer/restorer.go +++ b/internal/restorer/restorer.go @@ -272,7 +272,7 @@ func (res *Restorer) restoreNodeTo(ctx context.Context, node *restic.Node, targe return errors.Wrap(err, "RemoveNode") } - err := node.CreateAt(ctx, target, res.repo) + err := restic.NodeCreateAt(ctx, node, target, res.repo) if err != nil { debug.Log("node.CreateAt(%s) error %v", target, err) return err @@ -288,7 +288,7 @@ func (res *Restorer) restoreNodeMetadataTo(node *restic.Node, target, location s return nil } debug.Log("restoreNodeMetadata %v %v %v", node.Name, target, location) - err := node.RestoreMetadata(target, res.Warn) + err := restic.NodeRestoreMetadata(node, target, res.Warn) if err != nil { debug.Log("node.RestoreMetadata(%s) error %v", target, err) }