package restic import ( "path/filepath" "github.com/restic/restic/debug" "github.com/restic/restic/server" ) type WalkTreeJob struct { Path string Error error Node *Node Tree *Tree } func walkTree(s *server.Server, path string, treeBlob server.Blob, done chan struct{}, jobCh chan<- WalkTreeJob) { debug.Log("walkTree", "start on %q (%v)", path, treeBlob) // load tree t, err := LoadTree(s, treeBlob) if err != nil { jobCh <- WalkTreeJob{Path: path, Error: err} return } for _, node := range t.Nodes { p := filepath.Join(path, node.Name) if node.Type == "dir" { blob, err := t.Map.FindID(node.Subtree) if err != nil { jobCh <- WalkTreeJob{Path: p, Error: err} continue } walkTree(s, p, blob, done, jobCh) } else { // load old blobs node.blobs, err = t.Map.Select(node.Content) if err != nil { debug.Log("walkTree", "unable to load bobs for %q (%v): %v", path, treeBlob, err) } jobCh <- WalkTreeJob{Path: p, Node: node, Error: err} } } jobCh <- WalkTreeJob{Path: filepath.Join(path), Tree: t} debug.Log("walkTree", "done for %q (%v)", path, treeBlob) } // WalkTree walks the tree specified by ID recursively and sends a job for each // file and directory it finds. When the channel done is closed, processing // stops. func WalkTree(server *server.Server, blob server.Blob, done chan struct{}, jobCh chan<- WalkTreeJob) { debug.Log("WalkTree", "start on %v", blob) walkTree(server, "", blob, done, jobCh) close(jobCh) debug.Log("WalkTree", "done") }