forked from TrueCloudLab/restic
local: Replace matching code with proper Readdir()
This commit is contained in:
parent
4ae16d7661
commit
17f5b524a6
1 changed files with 63 additions and 10 deletions
|
@ -235,31 +235,84 @@ func (b *Local) Remove(t backend.Type, name string) error {
|
||||||
return os.Remove(fn)
|
return os.Remove(fn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func isFile(fi os.FileInfo) bool {
|
||||||
|
return fi.Mode()&(os.ModeType|os.ModeCharDevice) == 0
|
||||||
|
}
|
||||||
|
|
||||||
|
func readdir(d string) (fileInfos []os.FileInfo, err error) {
|
||||||
|
f, e := os.Open(d)
|
||||||
|
if e != nil {
|
||||||
|
return nil, e
|
||||||
|
}
|
||||||
|
|
||||||
|
defer func() {
|
||||||
|
e := f.Close()
|
||||||
|
if err == nil {
|
||||||
|
err = e
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
return f.Readdir(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
// listDir returns a list of all files in d.
|
||||||
|
func listDir(d string) (filenames []string, err error) {
|
||||||
|
fileInfos, err := readdir(d)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fi := range fileInfos {
|
||||||
|
if isFile(fi) {
|
||||||
|
filenames = append(filenames, fi.Name())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return filenames, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// listDirs returns a list of all files in directories within d.
|
||||||
|
func listDirs(dir string) (filenames []string, err error) {
|
||||||
|
fileInfos, err := readdir(dir)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fi := range fileInfos {
|
||||||
|
if !fi.IsDir() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
files, err := listDir(filepath.Join(dir, fi.Name()))
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
filenames = append(filenames, files...)
|
||||||
|
}
|
||||||
|
|
||||||
|
return filenames, nil
|
||||||
|
}
|
||||||
|
|
||||||
// List returns a channel that yields all names of blobs of type t. A
|
// List returns a channel that yields all names of blobs of type t. A
|
||||||
// goroutine is started for this. If the channel done is closed, sending
|
// goroutine is started for this. If the channel done is closed, sending
|
||||||
// stops.
|
// stops.
|
||||||
func (b *Local) List(t backend.Type, done <-chan struct{}) <-chan string {
|
func (b *Local) List(t backend.Type, done <-chan struct{}) <-chan string {
|
||||||
var pattern string
|
lister := listDir
|
||||||
if t == backend.Data {
|
if t == backend.Data {
|
||||||
pattern = filepath.Join(dirname(b.p, t, ""), "*", "*")
|
lister = listDirs
|
||||||
} else {
|
|
||||||
pattern = filepath.Join(dirname(b.p, t, ""), "*")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ch := make(chan string)
|
ch := make(chan string)
|
||||||
matches, err := filepath.Glob(pattern)
|
items, err := lister(filepath.Join(dirname(b.p, t, "")))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
close(ch)
|
close(ch)
|
||||||
return ch
|
return ch
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := range matches {
|
|
||||||
matches[i] = filepath.Base(matches[i])
|
|
||||||
}
|
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
defer close(ch)
|
defer close(ch)
|
||||||
for _, m := range matches {
|
for _, m := range items {
|
||||||
if m == "" {
|
if m == "" {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue