From b67c302834f7914476ef18043aa3b05861323573 Mon Sep 17 00:00:00 2001 From: Lenni vH Date: Sat, 27 Mar 2021 13:04:48 +0100 Subject: [PATCH] split in two files --- iterator.go | 107 ++++++++++++++++++++++++++++++++++++++++++++++++++++ main.go | 97 +---------------------------------------------- 2 files changed, 108 insertions(+), 96 deletions(-) create mode 100644 iterator.go diff --git a/iterator.go b/iterator.go new file mode 100644 index 0000000..65dfee5 --- /dev/null +++ b/iterator.go @@ -0,0 +1,107 @@ +package main + +import ( + "os" + "path/filepath" +) + +func iteratePaths() { + filesLock.RLock() + uPlen := len(unsearchedPaths) + + for uPlen > 0 { + next := unsearchedPaths[0] + unsearchedPaths = unsearchedPaths[1:] // discard that element + filesLock.RUnlock() + + var err error + var stat os.FileInfo + stat, err = os.Lstat(next) + // TODO don't exit on missing file, coreutils cp doesnt do that + if err != nil { + errMissingFile(err, next) + } + if stat.IsDir() { + dir, err := os.Open(next) + if err != nil { + errMissingFile(err, next) + } + var names []string + // TODO dont read all files at once, specify an amount of files to read + // and recall Readdirnames until io.EOF is returned (I guess) + names, err = dir.Readdirnames(0) + if err != nil { + errMissingFile(err, next) + } + + filesLock.Lock() + if createFoldersInTarget { + folders = append(folders, + filepath.Join(uPTargets[next], filepath.Base(next))) + } + var fileInFolder string + for _, fileInFolder = range names { + unsearchedPaths = append(unsearchedPaths, filepath.Join(next, fileInFolder)) + + if createFoldersInTarget { + uPTargets[filepath.Join(next, fileInFolder)] = filepath.Join(uPTargets[next], filepath.Base(next)) + } else { + uPTargets[filepath.Join(next, fileInFolder)] = uPTargets[next] + } + } + // three possibilities: + // - only one *file* is passed and should be duplicated. + // we don't care about creating folders in the target + // as there aren't any to create anyways + // - only one *folder* is passed and should be duplicated. + // this if statement is the very first to be called and + // this variable is subsequently set to true + // - multiple files and folders are passed and should be copied + // into a target, this variable was already set to true in main + createFoldersInTarget = true + fullSize += uint64(folderSize) + filesLock.Unlock() + } else if stat.Mode().IsRegular() { + filesLock.Lock() + fileOrder = append(fileOrder, next) + targets[next] = uPTargets[next] + filesLock.Unlock() + fullSize += uint64(stat.Size()) + } else if stat.Mode()&os.ModeDevice != 0 { + warnBadFile(next) + } else if stat.Mode()&os.ModeSymlink != 0 { + filesLock.Lock() + var nextTarget string = uPTargets[next] + if followSymlinks == 1 { + fileOrder = append(fileOrder, next) + targets[next] = nextTarget + fullSize += uint64(symlinkSize) + } else if followSymlinks == 2 { + nextResolved, err := os.Readlink(next) + if err != nil { + errReadingSymlink(err, next) + } + unsearchedPaths = append(unsearchedPaths, nextResolved) + uPTargets[nextResolved] = nextTarget + } + filesLock.Unlock() + } else { + warnBadFile(next) + } + + filesLock.RLock() + uPlen = len(unsearchedPaths) + } + + // close the l + filesLock.RUnlock() + + iteratorDone = true + fullAmount = uint64(len(fileOrder)) + + verbDoneIterating() + verbTargets() + + // as this function is forked anyways we can directly call this: + drawLoop() +} diff --git a/main.go b/main.go index f514919..2fb0557 100644 --- a/main.go +++ b/main.go @@ -59,100 +59,6 @@ var doReadConfig bool = true var start time.Time -func iteratePaths() { - filesLock.RLock() - var uPlen int = len(unsearchedPaths) - for uPlen > 0 { - var next string = unsearchedPaths[0] - unsearchedPaths = unsearchedPaths[1:] // discard first element - filesLock.RUnlock() - - var err error - var stat os.FileInfo - stat, err = os.Lstat(next) - // TODO don't exit on missing file, coreutils cp doesnt do that - if err != nil { - errMissingFile(err, next) - } - if stat.IsDir() { - dir, err := os.Open(next) - if err != nil { - errMissingFile(err, next) - } - var names []string - // TODO dont read all files at once, specify an amount of files to read - // and recall Readdirnames until io.EOF is returned (I guess) - names, err = dir.Readdirnames(0) - if err != nil { - errMissingFile(err, next) - } - - filesLock.Lock() - if createFoldersInTarget { - folders = append(folders, - filepath.Join(uPTargets[next], filepath.Base(next))) - } - var fileInFolder string - for _, fileInFolder = range names { - unsearchedPaths = append(unsearchedPaths, filepath.Join(next, fileInFolder)) - if createFoldersInTarget { - uPTargets[filepath.Join(next, fileInFolder)] = filepath.Join(uPTargets[next], filepath.Base(next)) - } else { - uPTargets[filepath.Join(next, fileInFolder)] = uPTargets[next] - } - } - // three possibilities: - // - only one *file* is passed and should be duplicated. - // we don't care about creating folders in the target - // as there aren't any to create anyways - // - only one *folder* is passed and should be duplicated. - // this if statement is the very first to be called and - // this variable is subsequently set to true - // - multiple files and folders are passed and should be copied - // into a target, this variable was already set to true in main - createFoldersInTarget = true - fullSize += uint64(folderSize) - filesLock.Unlock() - } else if stat.Mode().IsRegular() { - filesLock.Lock() - fileOrder = append(fileOrder, next) - targets[next] = uPTargets[next] - filesLock.Unlock() - fullSize += uint64(stat.Size()) - } else if stat.Mode()&os.ModeDevice != 0 { - warnBadFile(next) - } else if stat.Mode()&os.ModeSymlink != 0 { - filesLock.Lock() - var nextTarget string = uPTargets[next] - if followSymlinks == 1 { - fileOrder = append(fileOrder, next) - targets[next] = nextTarget - fullSize += uint64(symlinkSize) - } else if followSymlinks == 2 { - nextResolved, err := os.Readlink(next) - if err != nil { - errReadingSymlink(err, next) - } - unsearchedPaths = append(unsearchedPaths, nextResolved) - uPTargets[nextResolved] = nextTarget - } - filesLock.Unlock() - } else { - warnBadFile(next) - } - filesLock.RLock() - uPlen = len(unsearchedPaths) - } - filesLock.RUnlock() - iteratorDone = true - fullAmount = uint64(len(fileOrder)) - verbDoneIterating() - verbTargets() - - // as this function is forked anyways we can directly call this: - drawLoop() -} - func main() { var err error @@ -162,8 +68,7 @@ func main() { var kvs []string kvs, err = config.Load() if err == nil { - var line string - for _, line = range kvs { + for _, line := range kvs { parseOption(line) } } else {