in oss/lib/cp.go [1775:1856]
func (cc *CopyCommand) getFileListStatistic(dpath string) error {
if cc.cpOption.onlyCurrentDir {
return cc.getCurrentDirFilesStatistic(dpath)
}
name := dpath
symlinkDiretorys := []string{dpath}
walkFunc := func(fpath string, f os.FileInfo, err error) error {
if f == nil {
return err
}
if !cc.filterPath(fpath, cc.cpOption.cpDir) {
return nil
}
realFileSize := f.Size()
dpath = filepath.Clean(dpath)
fpath = filepath.Clean(fpath)
fileName, err := filepath.Rel(dpath, fpath)
if err != nil {
return fmt.Errorf("list file error: %s, info: %s", fpath, err.Error())
}
if f.IsDir() {
if fpath != dpath {
cc.monitor.updateScanNum(1)
}
return nil
}
if cc.cpOption.disableAllSymlink && (f.Mode()&os.ModeSymlink) != 0 {
return nil
}
// link file or link dir
if f.Mode()&os.ModeSymlink != 0 {
// there is difference between os.Stat and os.Lstat in filepath.Walk
realInfo, err := os.Stat(fpath)
if err != nil {
return err
}
if realInfo.IsDir() {
realFileSize = 0
} else {
realFileSize = realInfo.Size()
}
if cc.cpOption.enableSymlinkDir && realInfo.IsDir() {
// it's symlink dir
// if linkDir has suffix os.PathSeparator,os.Lstat determine it is a dir
if !strings.HasSuffix(name, string(os.PathSeparator)) {
name += string(os.PathSeparator)
}
linkDir := name + fileName + string(os.PathSeparator)
symlinkDiretorys = append(symlinkDiretorys, linkDir)
return nil
}
}
if doesSingleFileMatchPatterns(f.Name(), cc.cpOption.filters) {
cc.monitor.updateScanSizeNum(realFileSize, 1)
}
return nil
}
var err error
for {
symlinks := symlinkDiretorys
symlinkDiretorys = []string{}
for _, v := range symlinks {
err = filepath.Walk(v, walkFunc)
if err != nil {
return err
}
}
if len(symlinkDiretorys) == 0 {
break
}
}
return err
}