func CollectGarbage(namesToLeave []string, dryRun bool) error { if len(namesToLeave) == 0 { return nil } usedRefs := make(map[block.Ref]int) for _, name := range namesToLeave { info, err := LoadInfo(name) if err != nil { return err } // Walk and mark used refs. usedRefs[*info.DirRef]++ err = dir.Walk(info.DirRef, func(path string, file *dir.Entry) error { return block.WalkRefs(file.Ref, func(ref *block.Ref) error { usedRefs[*ref]++ return nil }) }) if err != nil { return err } } // Remove unused blocks. err := filepath.Walk(config.BlocksPath, func(path string, fi os.FileInfo, err error) error { if fi.Mode().IsDir() { if len(fi.Name()) != 2 && path != config.BlocksPath { return filepath.SkipDir // not a block directory, skip } return nil } ref := block.RefFromHex([]byte(filepath.Base(filepath.Dir(path)) + fi.Name())) if ref == nil { return nil // not a block, skip } if n, ok := usedRefs[*ref]; ok || n > 0 { return nil // block is used } if !dryRun { // Block unused, remove it. log.Printf("removing unused block %s", ref) return os.Remove(path) } else { fmt.Printf("unused block %s\n", ref) } return nil }) if err != nil { return err } return nil }
func showRef() error { if flag.NArg() < 2 || flag.Arg(1) == "" { return fmt.Errorf("expecting block ref") } ref := block.RefFromHex([]byte(flag.Arg(1))) if ref == nil { return fmt.Errorf("bad ref %s", flag.Arg(1)) } r, err := block.NewReader(ref) if err != nil { return err } if _, err := io.Copy(os.Stdout, r); err != nil { return err } return nil }
func dirHandler(w http.ResponseWriter, req *http.Request) { refName := path.Base(req.URL.Path) //TODO reject other paths. dirRef := block.RefFromHex([]byte(refName)) if dirRef == nil { http.Error(w, fmt.Sprintf("Bad ref"), http.StatusBadRequest) return } files, err := dir.LoadDirectory(dirRef) if err != nil { http.Error(w, err.Error(), http.StatusNotFound) return } rows := make([]fileDesc, len(files)) for i, f := range files { var r fileDesc r.IsDir = f.Mode.IsDir() r.Name = f.Name r.Mode = f.Mode.String() r.Time = f.ModTime.Local().Format("02 Jan 2006 15:04") r.Size = sizeString(f.Size) r.Ref = f.Ref.String() rows[i] = r } sort.Sort(fileDescSlice(rows)) var b bytes.Buffer if err := dirTemplate.Execute(&b, &struct { Title string DirRef *block.Ref Files []fileDesc }{ "Directory", dirRef, rows, }); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } b.WriteTo(w) }
func listFiles() error { if flag.NArg() < 2 || flag.Arg(1) == "" { return fmt.Errorf("expecting snapshot name or directory ref") } var dirRef *block.Ref if snapshot.IsValidName(flag.Arg(1)) { // Given snapshot ref, fetch index ref. si, err := snapshot.LoadInfo(flag.Arg(1)) if err != nil { return err } dirRef = si.DirRef } else { dirRef = block.RefFromHex([]byte(flag.Arg(1))) if dirRef == nil { return fmt.Errorf("bad ref %q", flag.Arg(1)) } } return listDirectory("", dirRef) }