Skip to content

Commit

Permalink
feat: implement following symlinks
Browse files Browse the repository at this point in the history
This feature lets us replace symlinks to files with the actual files they point to. Symlinks to directories are NOT walked. Symlinks to non-regular files will remain symlinks.
  • Loading branch information
d-Rickyy-b committed Feb 11, 2021
1 parent d5d0aab commit a98fe65
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 7 deletions.
27 changes: 20 additions & 7 deletions archiver/archive.go
Original file line number Diff line number Diff line change
Expand Up @@ -108,23 +108,36 @@ func writeZip(archiveFile *os.File, filesToBackup []BackupFileMetadata) {
}

func addFileToTar(tw *tar.Writer, path string, pathInArchive string) error {
file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()

if stat, err := os.Lstat(path); err == nil {
var linkTarget string
// Check if file is symlink
if stat.Mode()&os.ModeSymlink != 0 {
log.Printf("Found link: %s", path)
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 {
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
}
}
}
}
}

file, err := os.Open(path)
if err != nil {
return err
}
defer file.Close()

// now lets create the header as needed for this file within the tarball
header, err := tar.FileInfoHeader(stat, filepath.ToSlash(linkTarget))
Expand Down
7 changes: 7 additions & 0 deletions config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ type Unit struct {
AddSubfolder bool
Enabled bool
UseAbsolutePaths bool
FollowSymlinks bool
}

type Config struct {
Expand All @@ -32,6 +33,7 @@ type yamlUnit struct {
AddSubfolder *bool `yaml:"add_subfolder"`
Enabled *bool `yaml:"enabled"`
UseAbsolutePaths *bool `yaml:"use_absolute_paths"`
FollowSymlinks *bool `yaml:"follow_symlinks"`
}

func (config Config) FromYaml(yamlData []byte) (Config, error) {
Expand Down Expand Up @@ -75,6 +77,11 @@ func (config Config) FromYaml(yamlData []byte) (Config, error) {
unit.UseAbsolutePaths = *yamlUnit.UseAbsolutePaths
}

unit.FollowSymlinks = false
if yamlUnit.FollowSymlinks != nil {
unit.FollowSymlinks = *yamlUnit.FollowSymlinks
}

if yamlUnit.Sources == nil || yamlUnit.Destination == nil {
log.Fatalf("Sources or destination can't be parsed for unit '%s'", unitName)
} else {
Expand Down

0 comments on commit a98fe65

Please sign in to comment.