From 3e29d17625b117d2a674d95a3399b50cbee3577a Mon Sep 17 00:00:00 2001 From: Neeraj Gupta <254676+ua741@users.noreply.github.com> Date: Wed, 18 Oct 2023 13:55:29 +0530 Subject: [PATCH] Fix: Handle rename across volumes --- pkg/disk.go | 40 ++++++++++++++++++++++++++++++++++++++ pkg/remote_to_disk_file.go | 6 +++--- 2 files changed, 43 insertions(+), 3 deletions(-) diff --git a/pkg/disk.go b/pkg/disk.go index adb9345fc..2a81d4976 100644 --- a/pkg/disk.go +++ b/pkg/disk.go @@ -5,7 +5,9 @@ import ( "cli-go/pkg/model/export" "encoding/json" "errors" + "io" "os" + "strings" ) const ( @@ -96,3 +98,41 @@ func readJSONFromFile(filePath string, data interface{}) error { decoder := json.NewDecoder(file) return decoder.Decode(data) } + +func Move(source, destination string) error { + err := os.Rename(source, destination) + if err != nil && strings.Contains(err.Error(), "cross-device link") { + return moveCrossDevice(source, destination) + } + return err +} + +func moveCrossDevice(source, destination string) error { + src, err := os.Open(source) + if err != nil { + return err + } + dst, err := os.Create(destination) + if err != nil { + src.Close() + return err + } + _, err = io.Copy(dst, src) + src.Close() + dst.Close() + if err != nil { + return err + } + fi, err := os.Stat(source) + if err != nil { + os.Remove(destination) + return err + } + err = os.Chmod(destination, fi.Mode()) + if err != nil { + os.Remove(destination) + return err + } + os.Remove(source) + return nil +} diff --git a/pkg/remote_to_disk_file.go b/pkg/remote_to_disk_file.go index 3dbe27bf7..a1c861414 100644 --- a/pkg/remote_to_disk_file.go +++ b/pkg/remote_to_disk_file.go @@ -145,11 +145,11 @@ func (c *ClICtrl) downloadEntry(ctx context.Context, imageFilePath := filepath.Join(diskInfo.ExportRoot, diskInfo.AlbumMeta.FolderName, imageFileName) videoFilePath := filepath.Join(diskInfo.ExportRoot, diskInfo.AlbumMeta.FolderName, videoFileName) // move the decrypt file to filePath - err = os.Rename(imagePath, imageFilePath) + err = Move(imagePath, imageFilePath) if err != nil { return err } - err = os.Rename(videoPath, videoFilePath) + err = Move(videoPath, videoFilePath) if err != nil { return err } @@ -159,7 +159,7 @@ func (c *ClICtrl) downloadEntry(ctx context.Context, fileName := baseFileName + extension filePath := filepath.Join(diskInfo.ExportRoot, diskInfo.AlbumMeta.FolderName, fileName) // move the decrypt file to filePath - err = os.Rename(*decrypt, filePath) + err = Move(*decrypt, filePath) if err != nil { return err }