diff --git a/main.go b/main.go index 5a1393d..e29dff2 100644 --- a/main.go +++ b/main.go @@ -296,12 +296,12 @@ func downloadURL(ctx context.Context, client *http.Client, url string, config Co } targetPath := filepath.Join(config.OutputDir, targetFilename) - // Close the temp file before moving it + // Close the temp file before copying its contents tempFile.Close() - // Move the temp file to the target location - if err := os.Rename(tempFilePath, targetPath); err != nil { - return fmt.Errorf("failed to move file: %w", err) + // Fix: Instead of using os.Rename, copy the file contents to handle cross-partition moves + if err := copyFileAcrossPartitions(tempFilePath, targetPath); err != nil { + return fmt.Errorf("failed to copy file: %w", err) } // Parse Last-Modified header @@ -343,6 +343,46 @@ func downloadURL(ctx context.Context, client *http.Client, url string, config Co return nil } +// copyFileAcrossPartitions safely copies a file across different partitions +func copyFileAcrossPartitions(srcPath, dstPath string) error { + // Open source file for reading + srcFile, err := os.Open(srcPath) + if err != nil { + return fmt.Errorf("failed to open source file: %w", err) + } + defer srcFile.Close() + + // Create destination file + dstFile, err := os.Create(dstPath) + if err != nil { + return fmt.Errorf("failed to create destination file: %w", err) + } + defer dstFile.Close() + + // Copy contents + _, err = io.Copy(dstFile, srcFile) + if err != nil { + return fmt.Errorf("failed to copy file contents: %w", err) + } + + // Sync file to ensure all data is written to disk + if err := dstFile.Sync(); err != nil { + return fmt.Errorf("failed to sync file: %w", err) + } + + // Close the files explicitly before removing the source + srcFile.Close() + dstFile.Close() + + // Remove the temporary file + if err := os.Remove(srcPath); err != nil { + log.Printf("Warning: Failed to remove temporary file %s: %v", srcPath, err) + // Continue even if we couldn't remove the temp file + } + + return nil +} + // findExistingFile checks if a file with the given SHA-1 checksum already exists func findExistingFile(metadataDir, sha1sum string) (string, bool) { metadataPath := filepath.Join(metadataDir, sha1sum+".json")