package main import ( "flag" "log" "os" "strings" "syscall" ) type Ent struct { name []string mtime int64 size int64 } func (ent *Ent) IsDir() bool { return IsDir(ent.name[len(ent.name)-1]) } func dbCommit(dbPath string, tmp *os.File) { umask := syscall.Umask(0) syscall.Umask(umask) if err := os.Chmod(tmp.Name(), os.FileMode(0666&^umask)); err != nil { log.Fatalln(err) } if err := os.Rename(tmp.Name(), dbPath); err != nil { log.Fatalln(err) } } func main() { dbPath := flag.String("db", "glocate.db", "Path to database") doIndex := flag.Bool("index", false, "Perform indexing") doUpdate := flag.Bool("update", false, "Feed zfs-diff and update the database") strip := flag.String("strip", "", "Strip prefix from zfs-diff's paths") showMachine := flag.Bool("machine", false, "Show machine friendly") showTree := flag.Bool("tree", false, "Show human-friendly tree") dryRun := flag.Bool("n", false, "Dry run, do not overwrite database") flag.Parse() log.SetFlags(log.Ldate | log.Ltime | log.Lmicroseconds | log.Lshortfile) if *doIndex { tmp := index() tmp.Close() if !*dryRun { dbCommit(*dbPath, tmp) } return } if *doUpdate { tmp := updateWithDiff(*dbPath, *strip) tmp.Close() if !*dryRun { dbCommit(*dbPath, tmp) } return } db, err := os.Open(*dbPath) if err != nil { log.Fatalln(err) } entsReader := make(chan Ent, 1<<10) go reader(db, entsReader) entsPrinter := make(chan Ent, 1<<10) printerJob := make(chan struct{}) go func() { if *showMachine { printerMachine(entsPrinter) } else if *showTree { printerTree(entsPrinter) } else { printerSimple(entsPrinter) } close(printerJob) }() var root []string if len(flag.Args()) > 0 { root = strings.Split("./"+flag.Arg(0), "/") } rootMet := false for ent := range entsReader { if hasPrefix(ent.name, root) { entsPrinter <- ent rootMet = true } else if rootMet { break } } close(entsPrinter) <-printerJob }