Skip to content

Commit

Permalink
fix: add better error handling in addFileToTar
Browse files Browse the repository at this point in the history
  • Loading branch information
d-Rickyy-b committed Aug 22, 2021
1 parent 90a8af0 commit bde2db8
Showing 1 changed file with 55 additions and 42 deletions.
97 changes: 55 additions & 42 deletions archiver/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package archiver
import (
"archive/tar"
"backmeup/config"
"errors"
"fmt"
"github.com/cheggaaa/pb/v3"
"github.com/klauspost/compress/gzip"
Expand Down Expand Up @@ -108,56 +109,68 @@ func writeZip(archiveFile *os.File, filesToBackup []BackupFileMetadata) {
}

func addFileToTar(tw *tar.Writer, path string, pathInArchive string) error {
if stat, err := os.Lstat(path); err == nil {
var linkTarget string
// Check if file is symlink
if stat.Mode()&os.ModeSymlink != 0 {
var err error
linkTarget, err = os.Readlink(path)
if err != nil {
return fmt.Errorf("%s: readlink: %v", stat.Name(), err)
stat, statErr := os.Lstat(path)
if statErr != nil {
return statErr
}
var linkTarget string
// Check if file is symlink
if stat.Mode()&os.ModeSymlink != 0 {
var err error
linkTarget, err = os.Readlink(path)
if err != nil {
return fmt.Errorf("%s: readlink: %v", stat.Name(), err)
}

// In case the user wants to follow symlinks we eval the symlink target
if currentUnitConfig.FollowSymlinks {
linkTargetPath, evalSymlinkErr := filepath.EvalSymlinks(path)
if evalSymlinkErr != nil {
return evalSymlinkErr
}

// In case the user wants to follow symlinks we eval the symlink target
if currentUnitConfig.FollowSymlinks {
if linkTargetPath, err := filepath.EvalSymlinks(path); err == nil {
if linkTargetInfo, statErr := os.Stat(linkTargetPath); statErr == nil {
if linkTargetInfo.Mode().IsRegular() {
// If file is regular, we can simply replace the symlink with the actual file
path = linkTargetPath
linkTarget = ""
stat = linkTargetInfo
}
}
}
linkTargetInfo, linkTargetStatErr := os.Stat(linkTargetPath)
if linkTargetStatErr != nil {
log.Printf("Can't access link target!")
return linkTargetStatErr
}
}

file, err := os.Open(path)
if err != nil {
return err
if linkTargetInfo.Mode().IsRegular() {
// If file is regular, we can simply replace the symlink with the actual file
path = linkTargetPath
linkTarget = ""
stat = linkTargetInfo
} else {
log.Printf("Can't access link target. File is not regular!")
return errors.New("file is not regular")
}
}
defer file.Close()
}

// now lets create the header as needed for this file within the tarball
header, err := tar.FileInfoHeader(stat, filepath.ToSlash(linkTarget))
if err != nil {
return nil
}
header.Name = pathInArchive
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()

// write the header to the tarball archiver
if err := tw.WriteHeader(header); err != nil {
return err
}
// now lets create the header as needed for this file within the tarball
header, err := tar.FileInfoHeader(stat, filepath.ToSlash(linkTarget))
if err != nil {
return err
}
header.Name = pathInArchive

// Check for regular files
if stat.Mode().IsRegular() {
// copy the file data to the tarball
_, err := io.Copy(tw, file)
if err != nil {
return fmt.Errorf("%s: copying contents: %w", file.Name(), err)
}
// write the header to the tarball archiver
if err := tw.WriteHeader(header); err != nil {
return err
}

// Check for regular files
if stat.Mode().IsRegular() {
// copy the file data to the tarball
_, err := io.Copy(tw, file)
if err != nil {
return fmt.Errorf("%s: copying contents: %w", file.Name(), err)
}
}

Expand Down

0 comments on commit bde2db8

Please sign in to comment.